home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / CENVIW9.ZIP / COMM.LIB < prev    next >
Text File  |  1994-03-08  |  21KB  |  464 lines

  1. // Comm.lib - Windows routines for accessing (open, read, write, etc...)
  2. // ver.1      the COMM ports (serial ports, printer ports).  You may want
  3. //            to #include this file in your Cmm source, or just copy out
  4. //            the parts that you want.
  5. //
  6. //---- OpenComm(): Open COMM device and get handle to it -------------------
  7. // SYNTAX: int OpenComm(string CommName[,int ReadQueueSize,int WriteQueueSize])
  8. // WHERE: CommName: String name for the device, such as "COM1", "COM2", "LPT1", etc...
  9. //        ReadQueueSize, WriteQueueSize: Optional buffer sizes to prepare area
  10. //            for data to reside while it is being received or sent.  These
  11. //            values are ignored by Windows for LPT ports. If these
  12. //            are not supplied then they default to the following
  13.             #define DEFAULT_COMM_QUEUE_SIZE  500
  14. // RETURN: Returns a handle to the now-open communications device for subsequent
  15. //         calls to ReadComm(), WriteComm(), etc.  If error, then returns a
  16. //         negatvie value, which may be one of the following:
  17.       #define IE_BADID    (-1)   // Invalid or unsupported ID
  18.       #define IE_BAUDRATE (-12)  // Unsupported baud rate
  19.       #define IE_BYTESIZE (-11)  // Invalid byte size
  20.       #define IE_DEFAULT  (-5)   // Error in default parameters
  21.       #define IE_HARDWARE (-10)  // Hardware Not Present
  22.       #define IE_MEMORY   (-4)   // Unable to allocate queues
  23.       #define IE_NOPEN    (-3)   // Device not open
  24.       #define IE_OPEN     (-2)   // Device already open
  25. // NOTES: Call CloseComm before terminating your program. You may want to set
  26. //        up an atexit() function to ensure this.
  27. //
  28. //---- CloseComm(): Close COMM device opened with OpenComm ------------------
  29. // SYNTAX: int CloseComm(int CommHandle)
  30. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  31. // RETURN: Returns 0 for success, else a negative error. This call is expected
  32. //         to success and so most programmers don't test the return code.
  33. // NOTES: All characters in the output queue are sent before the device is closed.
  34. //
  35. //---- ReadComm(): Read characters from open COMM device ---------------------
  36. // SYNTAX: int ReadComm(int CommHandle,byte[] DestBuffer,int bufferLen[,int CommError])
  37. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  38. //        DestBuffer: Data will be read into this buffer, will be created as a
  39. //                    buffer if it is not already
  40. //        bufferLen: Maximum number of bytes to read into buffer
  41. //        CommError: If there is a communications error during read, then this will
  42. //                   be set to the error, else 0 for no error.  See CommError
  43. //                   values below.
  44. // RETURN: Returns number of bytes read, which is 0 up to bufferLen
  45. // NOTES: GetCommError() will always be called, whether or not the optional
  46. //        CommError is supplied in this function, to clear port errors.  If
  47. //        return value is bufferLen, then there may be more characters
  48. //        available.
  49. //
  50. //---- GetCommError(): Get COMM port error, and clear error -----------------
  51. // SYNTAX: int GetCommError(CommHandle,[struct CommStatus])
  52. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  53. //        CommStatus: an optional structure that will be set with the
  54. //        following elements
  55. //          bool fCtsHold     Transmit is on CTS hold
  56. //          bool fDsrHold     Transmit is on DSR hold
  57. //          bool fRlsdHold    Transmit is on RLSD hold
  58. //          bool fXoffHold    Received handshake
  59. //          bool fXoffSent    Issued handshake
  60. //          bool fEof         End of file character found
  61. //          bool fTxim        Character being transmitted
  62. //          int  cbInQue      count of characters in Rx Queue
  63. //          int  cbOutQue     count of characters in Tx Queue
  64. // RETURN: Return 0 for no error, else an error that may be an OR combination
  65. //         of the following:
  66.       #define CE_RXOVER    0x0001   // Receive Queue overflow
  67.       #define CE_OVERRUN   0x0002   // Receive Overrun Error
  68.       #define CE_RXPARITY  0x0004   // Receive Parity Error
  69.       #define CE_FRAME     0x0008   // Receive Framing error
  70.       #define CE_BREAK     0x0010   // Break Detected
  71.       #define CE_CTSTO     0x0020   // CTS Timeout
  72.       #define CE_DSRTO     0x0040   // DSR Timeout
  73.       #define CE_RLSDTO    0x0080   // RLSD Timeout
  74.       #define CE_TXFULL    0x0100   // TX Queue is full
  75.       #define CE_PTO       0x0200   // LPTx Timeout
  76.       #define CE_IOE       0x0400   // LPTx I/O Error
  77.       #define CE_DNS       0x0800   // LPTx Device not selected
  78.       #define CE_OOP       0x1000   // LPTx Out-Of-Paper
  79.       #define CE_MODE      0x8000   // Requested mode unsupported
  80. // NOTES: Many of the previous function call this function with no CommStatus
  81. //        just to clear any potential errors
  82. //
  83. //---- WriteComm: Write characters to open COMM device --------------------
  84. // SYNTAX: int WriteComm(int CommHandle,byte[] SrcBuffer,int bufferLen[,int CommError])
  85. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  86. //        SrcBuffer: Data will be written from this buffer
  87. //        bufferLen: Number of bytes to written from this buffer
  88. //        CommError: If there is a communications error during write, then this will
  89. //                   be set to the error, else 0 for no error.  See CommError
  90. //                   values below.
  91. // RETURN: Returns number of bytes written, which is 0 up to bufferLen. If less
  92. //         than bufferLen then there was certainly an error.
  93. // NOTES: GetCommError() will always be called, whether or not the optional
  94. //        CommError is supplied in this function, to clear port errors.  If there
  95. //        is not enough room in the output queue then some characters will be
  96. //        lost, and so if you're not sure there's enough room you may want to
  97. //        call GetCommError() to see how much room is available.
  98. //
  99. //
  100. //---- UngetCommChar: Place one character back into the receive queue -------
  101. // SYNTAX: int UngetCommChar(int CommHandle,byte Character)
  102. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  103. //        Character: Single character to place back in read queue
  104. // RETURN: Zero if successful, else negative error code
  105. // NOTES: You can only place one character back in the queue.  That character
  106. //        must be read out of the queue before placing another
  107. //
  108. //
  109. //---- TransmitCommChar: Place character at head of tranmsit queue ---------
  110. // SYNTAX: int TransmitCommChar(int CommHandle,byte Character)
  111. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  112. //        Character: Single character for immediate transmission
  113. // RETURN: Zero if successful, else negative error code.  Error if previous
  114. //         TransmitCommChar() has not been transmitted yet.
  115. //
  116. //
  117. //---- FlushComm: Flush all characters out of receive or transmit queue -----
  118. // SYNTAX: int FlushComm(int CommHandle,int WhichQueue)
  119. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  120. //        WhichQueue: 0 to flush transmit queue, else 1 to flush receive queue
  121. // RETURN: Zero if successful, else negative error code for invalid
  122. //         CommHandle or invalid WhichQueue.
  123. //
  124. //
  125. //---- SetCommBreak: Suspend transmission and fo to break state -------------
  126. // SYNTAX: int SetCommBreak(int CommHandle)
  127. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  128. // RETURN: Return 0 for success, else negative if CommHandle is invalid
  129. // NOTES: Suspends transmission and places the line in the break state until
  130. //        ClearCommBreak() is called.
  131. //
  132. //
  133. //---- ClearCommBreak: Restore transmission and set to non-break state ------
  134. // SYNTAX: int ClearCommBreak(int CommHandle)
  135. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  136. // RETURN: Return 0 for success, else negative if CommHandle is invalid
  137. //
  138. //
  139. //---- EscapeCommFunction: Perform an extended function ---------------------
  140. // SYNTAX: int EscapeCommFunction(int CommHandle,int ExtendedFunction)
  141. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  142. //        ExtendedFunction: One of the following values
  143.       #define CLRDTR    6  // Set DTR low
  144.       #define CLRRTS    4  // Set RTS low
  145.       #define RESETDEV  7  // Reset device if possible
  146.       #define SETDTR    5  // Set DTR high
  147.       #define SETRTS    3  // Set RTS high
  148.       #define SETXOFF   1  // Simulate XOFF received
  149.       #define SETXON    2  // Simulate XON received
  150. // RETURN: Return 0 for success, else negative if CommHandle or
  151. //         ExtendedFunction is invalid
  152. //
  153. //
  154. //---- SetCommEventMask: Retrieve and set events ----------------------
  155. // SYNTAX: int SetCommEventMask(int CommHandle,int EventMask)
  156. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  157. //        EventMask: Mask of bits for events to be enabled
  158.       #define EV_RXCHAR    0x0001   // Any Character received
  159.       #define EV_RXFLAG    0x0002   // Received certain character
  160.       #define EV_TXEMPTY   0x0004   // Transmitt Queue Empty
  161.       #define EV_CTS       0x0008   // CTS changed state
  162.       #define EV_DSR       0x0010   // DSR changed state
  163.       #define EV_RLSD      0x0020   // RLSD changed state
  164.       #define EV_BREAK     0x0040   // BREAK received
  165.       #define EV_ERR       0x0080   // Line status error occurred
  166.       #define EV_RING      0x0100   // Ring signal detected
  167.       #define EV_PERR      0x0200   // Printer error occured
  168. // RETURN: Return integer event mask where each bit is set if that event has occured.
  169. //
  170. //
  171. //---- GetCommEventMask: Retrieve event mask and clear the mask ---------
  172. // SYNTAX: int GetCommEventMask(int CommHandle,int EventMask)
  173. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  174. //        EventMask: Mask of bits for events to be enabled, see SetCommEventMask()
  175. // RETURN: Return integer event mask where each bit is set if that event has occured.
  176. //
  177. //
  178. //---- GetCommState: Get port parameters for comm device ----------------
  179. // SYNTAX: int GetCommState(int CommHandle,struct dcb)
  180. // WHERE: CommHandle: value returned from previous successful call to OpenComm()
  181. //        dcb: Device control block to be set with the following members:
  182. //    int  Id               // Internal Device ID
  183. //    int  BaudRate         // Baud rate at which runing
  184. //    int  ByteSize         // Number of bits/byte, 4-8
  185. //    int  Parity           // 0-4=None,Odd,Even,Mark,Space
  186.          #define NOPARITY     0
  187.          #define ODDPARITY    1
  188.          #define EVENPARITY   2
  189.          #define MARKPARITY   3
  190.          #define SPACEPARITY  4
  191. //    int  StopBits         // 0,1,2 = 1, 1.5, 2
  192.          #define ONESTOPBIT   0
  193.          #define ONE5STOPBITS 1
  194.          #define TWOSTOPBITS  2
  195. //    int  RlsTimeout       // Timeout for RLSD to be set
  196. //    int  CtsTimeout       // Timeout for CTS to be set
  197. //    int  DsrTimeout       // Timeout for DSR to be set
  198. //    bool Binary           // Binary Mode (skip EOF check
  199. //    bool RtsDisable       // Don't assert RTS at init time
  200. //    bool Parity           // Enable parity checking
  201. //    bool OutxCtsFlow      // CTS handshaking on output
  202. //    bool OutxDsrFlow      // DSR handshaking on output
  203. //    bool DtrDisable       // Don't assert DTR at init time
  204. //    bool OutX             // Enable output X-ON/X-OFF
  205. //    bool InX              // Enable input X-ON/X-OFF
  206. //    bool PeChar           // Enable Parity Err Replacement
  207. //    bool NullStrip        // Enable Null stripping
  208. //    bool ChEvt            // Enable Rx character event.
  209. //    bool Dtrflow          // DTR handshake on input
  210. //    bool Rtsflow          // RTS handshake on input
  211. //    int  XonChar          // Tx and Rx X-ON character
  212. //    int  XoffChar         // Tx and Rx X-OFF character
  213. //    int  XonLim           // Transmit X-ON threshold
  214. //    int  XoffLim          // Transmit X-OFF threshold
  215. //    int  PeChar           // Parity error replacement char
  216. //    int  EofChar          // End of Input character
  217. //    int  EvtChar          // Received Event character
  218. //    int  TxDelay          // Amount of time between chars
  219. // RETURN: Return 0 for success, else negative error value
  220. //
  221. //
  222. //---- SetCommState: Set communication port parameters --------------------
  223. // SYNTAX: int SetCommState(struct dcb)
  224. // WHERE: dcb: Device control block to be set, with the same fields as described
  225. //             above in GetCommState()
  226. // RETURN: Return 0 for success, else negative error value
  227. // NOTES: ALL of the dcb fields must be define, and so it is recommended that
  228. //        have previously set the structure with a call to GetCommState() or
  229. //        BuildCommDCB.
  230. //
  231. //
  232. //---- BuildCommDCB: Translate definition string to device control block --
  233. // SYNTAX: int BuildCommDCB(string DeviceInfo,struct dcb)
  234. // WHERE: DeviceInfo: string for setting device information; this string
  235. //                    uses the same format as the DOS MODE command
  236. //        dcb: structure filled after translating DeviceInfo. This is same
  237. //             structure as described in GetCommState()
  238. // RETURN: Return 0 for success, else negative error value
  239. // NOTES: This only fills dcb; call SetCommState fo set device.  By default,
  240. //        Xon/Xoff flow control will be disabled
  241. //
  242. //
  243.  
  244.  
  245. /*****************************************************************
  246.  *********        END OF DESCRIPTION FOR COMM.LIB        *********
  247.  *****************************************************************/
  248.  
  249. OpenComm(CommName,ReadQueueSize,WriteQueueSize)
  250. {
  251.    // Get Queue sizes in case they weren't supplied
  252.    _ocReadQSize = ( 1 == va_arg() ) ? DEFAULT_COMM_QUEUE_SIZE : ReadQueueSize;
  253.    _ocWriteQSize = ( 1 == va_arg() ) ? DEFAULT_COMM_QUEUE_SIZE : WriteQueueSize;
  254.  
  255.    // Pass this call on to the Windows OpenComm routine
  256.    return DynamicLink("USER","OPENCOMM",SWORD16,PASCAL,
  257.                       CommName,_ocReadQSize,_ocWriteQSize);
  258. }
  259.  
  260. CloseComm(CommHandle)
  261. {
  262.    return DynamicLink("USER","CLOSECOMM",SWORD16,PASCAL,CommHandle);
  263. }
  264.  
  265. ReadComm(CommHandle,DestBuffer,bufferLen,CommError)
  266. {
  267.    // make sure DestBuffer is big enough
  268.    DestBuffer[bufferLen-1] = '\0';
  269.  
  270.    // Get value from Windows ReadComm function
  271.    _rcCount = DynamicLink("USER","READCOMM",SWORD16,PASCAL,
  272.                           CommHandle,DestBuffer,bufferLen);
  273.  
  274.    // If less then 1 byte read then take absolute, and might be error
  275.    if ( _rcCount < 1 ) {
  276.       _rcCount = abs(_rcCount);        // get absolute bytes read
  277.       _rcCommError = GetCommError(CommHandle);  // get error and clear it
  278.    } else
  279.       _rcCommError = 0;
  280.  
  281.    // If CommError was supplied then set it
  282.    if ( 3 < va_arg() )
  283.       CommError = _rcCommError;
  284.  
  285.    return _rcCount;
  286. }
  287.  
  288. WriteComm(CommHandle,DestBuffer,bufferLen,CommError)
  289. {
  290.    // Get value from Windows ReadComm function
  291.    _wcCount = DynamicLink("USER","WRITECOMM",SWORD16,PASCAL,
  292.                           CommHandle,DestBuffer,bufferLen);
  293.  
  294.    // If less then 1 byte written then take absolute, and might be error
  295.    if ( _wcCount < 1 ) {
  296.       _wcCount = abs(_wcCount);        // get absolute bytes read
  297.       _wcCommError = GetCommError(CommHandle);  // get error and clear it
  298.    } else
  299.       _wcCommError = 0;
  300.  
  301.    // If CommError was supplied then set it
  302.    if ( 3 < va_arg() )
  303.       CommError = _wcCommError;
  304.  
  305.    return _wcCount;
  306. }
  307.  
  308. GetCommError(CommHandle,CommStatus)
  309. {
  310.    if ( 1 == va_arg() ) {
  311.       // simple version, only return error code
  312.       _commError = DynamicLink("USER","GETCOMMERROR",SWORD16,PASCAL,
  313.                                CommHandle,0,0);
  314.    } else {
  315.       // CommStatus has been supplied, so must fill in the structure
  316.       BLObSize(_csBuf,5);
  317.       _commError = DynamicLink("USER","GETCOMMERROR",SWORD16,PASCAL,
  318.                                CommHandle,_csBuf);
  319.       _csBits = BLObGet(_csBuf,0,UWORD8);
  320.       CommStatus.fCtsHold  = (_csBits & 0x01) ? TRUE : FALSE ;
  321.       CommStatus.fDsrHold  = (_csBits & 0x02) ? TRUE : FALSE ;
  322.       CommStatus.fRlsdHold = (_csBits & 0x04) ? TRUE : FALSE ;
  323.       CommStatus.fXoffHold = (_csBits & 0x08) ? TRUE : FALSE ;
  324.       CommStatus.fXoffSent = (_csBits & 0x10) ? TRUE : FALSE ;
  325.       CommStatus.fEof      = (_csBits & 0x20) ? TRUE : FALSE ;
  326.       CommStatus.fTxim     = (_csBits & 0x40) ? TRUE : FALSE ;
  327.       CommStatus.cbInQue  = BLObGet(_csBuf,1,SWORD16);
  328.       CommStatus.cbOutQue = BLObGet(_csBuf,3,SWORD16);
  329.    }
  330.    return _commError;
  331. }
  332.  
  333. UngetCommChar(CommHandle,Character)
  334. {
  335.    return DynamicLink("USER","UNGETCOMMCHAR",SWORD16,PASCAL,CommHandle,Character);
  336. }
  337.  
  338. TransmitCommChar(CommHandle,Character)
  339. {
  340.    return DynamicLink("USER","TRANSMITCOMMCHAR",SWORD16,PASCAL,CommHandle,Character);
  341. }
  342.  
  343. FlushComm(CommHandle,WhichQueue)
  344. {
  345.    return DynamicLink("USER","FLUSHCOMM",SWORD16,PASCAL,CommHandle,WhichQueue);
  346. }
  347.  
  348. SetCommBreak(CommHandle)
  349. {
  350.    return DynamicLink("USER","SETCOMMBREAK",SWORD16,PASCAL,CommHandle);
  351. }
  352.  
  353. ClearCommBreak(CommHandle)
  354. {
  355.    return DynamicLink("USER","CLEARCOMMBREAK",SWORD16,PASCAL,CommHandle);
  356. }
  357.  
  358. EscapeCommFunction(CommHandle,ExtendedFunction)
  359. {
  360.    return DynamicLink("USER","ESCAPECOMMFUNCTION",SWORD16,PASCAL,
  361.                       CommHandle,ExtendedFunction);
  362. }
  363.  
  364. SetCommEventMask(CommHandle,EventMask)
  365. {
  366.    _EMaskPtr = DynamicLink("USER","SETCOMMEVENTMASK",UWORD32,PASCAL,CommHandle,EventMask);
  367.    return peek(_EMaskPtr,UWORD16);
  368. }
  369.  
  370. GetCommEventMask(CommHandle,EventMask)
  371. {
  372.    return DynamicLink("USER","GETCOMMEVENTMASK",UWORD16,PASCAL,CommHandle,EventMask);
  373. }
  374.  
  375. ConvertDCBblobTOstruct(b,s)
  376. {
  377.    s.Id           = BLObGet(b,0,UWORD8);
  378.    s.BaudRate     = BLObGet(b,1,UWORD16);
  379.    s.ByteSize     = BLObGet(b,3,UWORD8);
  380.    s.Parity       = BLObGet(b,4,UWORD8);
  381.    s.StopBits     = BLObGet(b,5,UWORD8);
  382.    s.RlsTimeout   = BLObGet(b,6,UWORD16);
  383.    s.CtsTimeout   = BLObGet(b,8,UWORD16);
  384.    s.DsrTimeout   = BLObGet(b,10,UWORD16);
  385.    _flags = BLObGet(b,12,UWORD8);
  386.    s.Binary       = _flags & 0x01;
  387.    s.RtsDisable   = _flags & 0x02;
  388.    s.Parity       = _flags & 0x04;
  389.    s.OutxCtsFlow  = _flags & 0x08;
  390.    s.OutxDsrFlow  = _flags & 0x10;
  391.    s.DtrDisable   = _flags & 0x80;
  392.    _flags = BLObGet(b,13,UWORD8);
  393.    s.OutX         = _flags & 0x01;
  394.    s.InX          = _flags & 0x02;
  395.    s.PeChar       = _flags & 0x04;
  396.    s.NullStrip    = _flags & 0x08;
  397.    s.ChEvt        = _flags & 0x10;
  398.    s.Dtrflow      = _flags & 0x20;
  399.    s.Rtsflow      = _flags & 0x40;
  400.    s.XonChar      = BLObGet(b,14,UWORD8);
  401.    s.XoffChar     = BLObGet(b,15,UWORD8);
  402.    s.XonLim       = BLObGet(b,16,UWORD16);
  403.    s.XoffLim      = BLObGet(b,18,UWORD16);
  404.    s.PeChar       = BLObGet(b,20,UWORD8);
  405.    s.EofChar      = BLObGet(b,21,UWORD8);
  406.    s.EvtChar      = BLObGet(b,22,UWORD8);
  407.    s.TxDelay      = BLObGet(b,23,UWORD16);
  408. }
  409.  
  410. GetCommState(CommHandle,dcb)
  411. {
  412.    BLObSize(_dcb,25);
  413.    _ret = DynamicLink("USER","GETCOMMSTATE",SWORD16,PASCAL,CommHandle,_dcb);
  414.    ConvertDCBblobTOstruct(_dcb,dcb);
  415.    return _ret;
  416. }
  417.  
  418. BuildCommDCB(DeviceInfo,dcb)
  419. {
  420.    BLObSize(_dcb,25);
  421.    _ret = DynamicLink("USER","BUILDCOMMDCB",SWORD16,PASCAL,DeviceInfo,_dcb);
  422.    ConvertDCBblobTOstruct(_dcb,dcb);
  423.    return _ret;
  424. }
  425.  
  426. SetCommState(dcb)
  427. {
  428.    BLObPut(_dcb,0,dcb.Id,UWORD8);
  429.    BLObPut(_dcb,1,dcb.BaudRate,UWORD16);
  430.    BLObPut(_dcb,3,dcb.ByteSize,UWORD8);
  431.    BLObPut(_dcb,4,dcb.Parity,UWORD8);
  432.    BLObPut(_dcb,5,dcb.StopBits,UWORD8);
  433.    BLObPut(_dcb,6,dcb.RlsTimeout,UWORD16);
  434.    BLObPut(_dcb,8,dcb.CtsTimeout,UWORD16);
  435.    BLObPut(_dcb,10,dcb.DsrTimeout,UWORD16);
  436.    _flags = 0;
  437.    if ( dcb.Binary )       _flags |= 0x01;
  438.    if ( dcb.RtsDisable)    _flags |= 0x02;
  439.    if ( dcb.Parity )       _flags |= 0x04;
  440.    if ( dcb.OutxCtsFlow )  _flags |= 0x08;
  441.    if ( dcb.OutxDsrFlow )  _flags |= 0x10;
  442.    if ( dcb.DtrDisable )   _flags |= 0x80;
  443.    BLObPut(_dcb,12,_flags,UWORD8);
  444.    _flags = 0;
  445.    if ( dcb.OutX )         _flags |= 0x01;
  446.    if ( dcb.InX )          _flags |= 0x02;
  447.    if ( dcb.PeChar )       _flags |= 0x04;
  448.    if ( dcb.NullStrip )    _flags |= 0x08;
  449.    if ( dcb.ChEvt )        _flags |= 0x10;
  450.    if ( dcb.Dtrflow )      _flags |= 0x20;
  451.    if ( dcb.Rtsflow )      _flags |= 0x40;
  452.    BLObPut(_dcb,13,_flags,UWORD8);
  453.    BLObPut(_dcb,14,dcb.XonChar,UWORD8);
  454.    BLObPut(_dcb,15,dcb.XoffChar,UWORD8);
  455.    BLObPut(_dcb,16,dcb.XonLim,UWORD16);
  456.    BLObPut(_dcb,18,dcb.XoffLim,UWORD16);
  457.    BLObPut(_dcb,20,dcb.PeChar,UWORD8);
  458.    BLObPut(_dcb,21,dcb.EofChar,UWORD8);
  459.    BLObPut(_dcb,22,dcb.EvtChar,UWORD8);
  460.    BLObPut(_dcb,23,dcb.TxDelay,UWORD16);
  461.    return DynamicLink("USER","SETCOMMSTATE",SWORD16,PASCAL,_dcb);
  462. }
  463.  
  464.