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

📄 ulibwin.c

📁 大量的汇编程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*--------------------------------------------------------------------*/
/*       u l i b w i n . C                                            */
/*                                                                    */
/*       UUPC/extended serial port communications for Windows 3.1     */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/*       Changes copyright (c) 1993, by Robert Denny                  */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
/*       Wonderworks.                                                 */
/*                                                                    */
/*       All rights reserved except those explicitly granted by       */
/*       the UUPC/extended license agreement.                         */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/*                          RCS Information                           */
/*--------------------------------------------------------------------*/

/*
 *    $Id: ulibwin.c 1.7 1993/10/03 22:09:09 ahd Exp $
 *
 *    Revision history:
 *    $Log: ulibwin.c $
 * Revision 1.7  1993/10/03  22:09:09  ahd
 * Use unsigned long to display speed
 *
 * Revision 1.6  1993/10/01  02:36:45  dmwatt
 * Suppress odd debugging messages in normal compile
 * Reformat source
 *
 * Revision 1.5  1993/09/29  13:18:06  ahd
 * Use new dummy setprty function
 *
 * Revision 1.4  1993/09/27  00:48:43  ahd
 * Add dummy set and reset priority functions
 *
 * Revision 1.3  1993/08/02  03:24:59  ahd
 * Further changes in support of Robert Denny's Windows 3.x support
 *
 * Revision 1.2  1993/07/31  16:27:49  ahd
 * Changes in support of Robert Denny's Windows support
 *
 * Revision 1.1  1993/07/22  23:24:23  ahd
 * Initial revision
 *
 */

/*--------------------------------------------------------------------*/
/*       Services provided by ulib.c:                                 */
/*                                                                    */
/*          - serial I/O                                              */
/*--------------------------------------------------------------------*/

/*--------------------------------------------------------------------*/
/*                        System include files                        */
/*--------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>

/*--------------------------------------------------------------------*/
/*                    MS Windows 3.1 include files                    */
/*--------------------------------------------------------------------*/

#include <windows.h>

/*--------------------------------------------------------------------*/
/*                    UUPC/extended include files                     */
/*--------------------------------------------------------------------*/

#include "lib.h"
#include "ulib.h"
#include "ssleep.h"
#include "commlib.h"

//
// Finally, Microsoft has documented a way to see the Modem Status
// Register bits for modem control lines. This was a real bizarre
// mess with SetCommEventMask() and GetCommEventMask(). The document
// is in the Developer's Knowledge Base:
//
// Title: INF: Accessing the Modem Status Register (MSR) in Windows
// Document Number: Q101417           Publ Date: 15-JUL-1993
// Product Name: Microsoft Windows Software Development Kit
// Product Version:  3.10
// Operating System: WINDOWS
//

#define COMM_MSRSHADOW 35          // Offset in DEB of MSR shadow
#define MSR_CTS              0x10  // absolute CTS state in MSR
#define MSR_DSR              0x20  // absolute DSR state in MSR
#define MSR_RI               0x40  // absolute RI state in MSR
#define MSR_RLSD             0x80  // absolute RLSD state in MSR

currentfile();

static boolean   carrierdetect = FALSE;  /* Modem is not connected     */

static boolean hangupNeeded = FALSE;
static UINT currentSpeed = 0;
static LPBYTE lpbModemBits;       // --> Modem Status Register bits

#define FAR_NULL ((PVOID) 0L)

#define IN_QUEUE_SIZE   2048
#define OUT_QUEUE_SIZE  2048
#define IN_XOFF_LIM     256
#define IN_XON_LIM      256

/*--------------------------------------------------------------------*/
/*         Definitions of control structures for Win 3.1 API          */
/*--------------------------------------------------------------------*/

static int nCid;
static DCB dcb;

/*--------------------------------------------------------------------*/
/*                        Internal prototypes                         */
/*--------------------------------------------------------------------*/

static void ShowModem( void );
static void ShowError( int status );

/*--------------------------------------------------------------------*/
/*    n o p e n l i n e                                               */
/*                                                                    */
/*    Open the serial port for I/O                                    */
/*--------------------------------------------------------------------*/

#ifdef __TURBOC__
#pragma argsused
#endif

int nopenline(char *name, BPS baud, const boolean direct )
{
   int rc;

   if (portActive)               /* Was the port already active?     ahd   */
      closeline();               /* Yes --> Shutdown it before open  ahd   */

#ifdef UDEBUG
   printmsg(15, "openline: %s, %ul", name, (unsigned long) baud);
#endif

   if (!equaln(name, "COM", 3 ))
   {
      printmsg(0,
         "openline: Communications port must be format COMx, was %s",
         name);
      return TRUE;
   }

   if((nCid = OpenComm(name, IN_QUEUE_SIZE, OUT_QUEUE_SIZE)) < 0)
   {
      printmsg(0, "openline: Failed to open port %s.", name);
      printmsg(0, "nopenline: %s: OpenComm returned %#04X (%d)",
                   name,
                   nCid,
                   nCid);
      return TRUE;
   }

/*--------------------------------------------------------------------*/
/*        Get the pointer to the MSR shadow in COMM.DRV's DEB         */
/*--------------------------------------------------------------------*/

   lpbModemBits = (LPBYTE)SetCommEventMask(nCid, 0) + COMM_MSRSHADOW;

/*--------------------------------------------------------------------*/
/*            Reset any errors on the communications port             */
/*--------------------------------------------------------------------*/

   if ((rc = GetCommError (nCid, NULL)) != 0)
   {
      printmsg(0, "openline: Error condition reset on port %s.", name);
      ShowError(rc);
   }

/*--------------------------------------------------------------------*/
/*                           Set baud rate                            */
/*--------------------------------------------------------------------*/

   nSIOSpeed(baud);

/*--------------------------------------------------------------------*/
/*                        Set line attributes                         */
/*--------------------------------------------------------------------*/

   printmsg(15,"openline: Getting attributes");
   if ((rc = GetCommState(nCid, &dcb)) != 0)
   {
      printmsg(0,"nopenline: %s: GetCommState was %#04x (%d)",
                  name,
                  rc,
                  rc);
      panic();
   }

   dcb.StopBits = ONESTOPBIT;
   dcb.Parity = NOPARITY;
   dcb.ByteSize = 8;

/*--------------------------------------------------------------------*/
/*                      Set up for Flow Control                       */
/*--------------------------------------------------------------------*/

   printmsg(15,"openline: Disabling XON/XOFF flow control");

   dcb.fOutX = 0;
   dcb.fInX = 0;
   if(!direct)                 // nodirect means RTS/CTS flow OK
   {
#ifdef UDEBUG
      printmsg(15, "openline: Enabling RTS/CTS flow control");
#endif
      dcb.fOutxCtsFlow = 1;
      dcb.fRtsflow = 1;
      dcb.XoffLim = IN_XOFF_LIM;
      dcb.XonLim = IN_XON_LIM;
   }
   else {
#ifdef UDEBUG
      printmsg(4, "openline: Disabling RTS/CTS flow control");
#endif
      dcb.fOutxCtsFlow = 0;
      dcb.fRtsflow = 0;
   }

/*--------------------------------------------------------------------*/
/*                Set up for Modem Control as needed                  */
/*--------------------------------------------------------------------*/

   dcb.fDtrDisable = 0;
   dcb.fRtsDisable = 0;

/*--------------------------------------------------------------------*/
/*              Modify the DCB with the new attributes                */
/*--------------------------------------------------------------------*/

#ifdef UDEBUG
   printmsg(15,"openline: Setting attributes");
#endif

   if ((rc = SetCommState(&dcb)) != 0)
   {
      printmsg(0,"nopenline: %s: return code from SetCommState was %#04X (%d)",
                 name,
                 rc,
                 rc);
      panic();
   }

/*--------------------------------------------------------------------*/
/*                 Assure RTS and DTR are asserted                    */
/*--------------------------------------------------------------------*/


#ifdef UDEBUG
   printmsg(15,"openline: Raising RTS/DTR");
#endif

   if (EscapeCommFunction(nCid, SETRTS) != 0)
   {
      printmsg(0, "openline: Failed to raise RTS for %s", name);
      panic();
   }
   if (EscapeCommFunction(nCid, SETDTR) != 0)
   {
      printmsg(0, "openline: Unable to raise DTR for %s", name);
      panic();
   }

   ShowModem();

/*--------------------------------------------------------------------*/
/*        Log serial line data only if log file already exists        */
/*--------------------------------------------------------------------*/

   traceStart( name );

   portActive = TRUE;     /* record status for error handler */

/*--------------------------------------------------------------------*/
/*                     Wait for port to stablize                      */
/*--------------------------------------------------------------------*/

   ssleep(2);              /* Allow port to stabilize per V.24  */

   return 0;

} /* nopenline */

/*--------------------------------------------------------------------*/
/*    s r e a d                                                       */
/*                                                                    */
/*    Read from the serial port                                       */
/*                                                                    */
/*   Non-blocking read essential to "g" protocol. The rather cryptic  */
/*   "description" in dcpgpkt.c is:                                   */
/*                                                                    */
/*   sread(buf, n, timeout)                                           */
/*      while(TRUE)                                                   */
/*         if # of chars available >= n (w/o dec internal counter)    */
/*            read n chars into buf (dec internal counter)            */
/*            break                                                   */
/*         else                                                       */
/*            if time > timeout                                       */
/*               break                                                */
/*                                                                    */
/*   NOTE: Timeout of 0 returns right away, indicating the number of  */
/*         bytes in our local receive buffer. There's GOTTA be a      */
/*         better way...                                              */
/*                                                                    */
/*   This all changes in a multi-tasking system.  Requests for I/O    */
/*   should get queued and an event flag given.  Then the             */
/*   requesting process (e.g. gmachine()) waits for the event flag    */
/*   to fire processing either a read or a write.  Could be           */
/*   implemented on VAX/VMS or DG but not MS-DOS.                     */
/*                                                                    */
/*--------------------------------------------------------------------*/

unsigned int nsread(char *output, unsigned int wanted, unsigned int timeout)

{
   int rc, received;
   time_t stop_time;
   time_t now;
   COMSTAT stat;

   //
   // This catches a fencepost condition later...
   //

   if (wanted == 0)
   {
      ddelay(0);
      return(0);
   }

/*--------------------------------------------------------------------*/
/*                      Report our modem status                       */
/*--------------------------------------------------------------------*/

  ShowModem();

/*--------------------------------------------------------------------*/
/*                 Determine when to stop processing                  */
/*--------------------------------------------------------------------*/

   if ( timeout == 0 )        /* 0 = don't wait around.               */
   {
      stop_time = 0;
      now = 1;                /* Any number greater than stop time    */
   }
   else {
      time( & now );
      stop_time = now + timeout;
   }

/*--------------------------------------------------------------------*/
/*       Watch RX Queue till wanted bytes available or timeout        */
/*--------------------------------------------------------------------*/

   while(TRUE)
   {

      //
      // Check & clear the comm port. This gets the #chars in the
      // receive queue as well, in the COMSTAT structure.
      //

      if ((rc = GetCommError(nCid, &stat)) != 0)
      {
         printmsg(0,"sread: Read of %d bytes failed.", wanted);
         printmsg(0,"       return code from GetCommError was %#04x (%d)",
                                                rc , rc);
         ShowError(rc);
         return 0;

⌨️ 快捷键说明

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