📄 ulibos2.c
字号:
rc = DosDevIOCtl( com_handle,
IOCTL_ASYNC,
ASYNC_SETMODEMCTRL,
(PVOID)&com_signals,
sizeof(com_signals),
&ParmLengthInOut,
(PVOID) &com_error,
sizeof(com_error),
&DataLengthInOut);
#else
rc = DosDevIOCtl( &com_error,
&com_signals,
ASYNC_SETMODEMCTRL,
IOCTL_ASYNC,
com_handle);
#endif
if (rc)
{
printmsg(0,
"nopenline: Unable to raise DTR/RTS for %s, error bits %#x",
name, (int) com_error );
printOS2error( "DosDevIOCtl", rc );
panic();
} /*if */
traceStart( name ); // Enable logging
portActive = TRUE; /* record status for error handler */
carrierDetect = FALSE; /* Modem is not connected */
/*--------------------------------------------------------------------*/
/* Wait for port to stablize */
/*--------------------------------------------------------------------*/
ddelay(500); /* Allow port to stablize */
return 0;
} /*nopenline*/
/*--------------------------------------------------------------------*/
/* n s r e a d */
/* */
/* Read from the serial port */
/* */
/* Non-blocking read essential to "g" protocol. See "dcpgpkt.c" */
/* for description. */
/* */
/* 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. */
/* */
/* OS/2 we could multitask, but we just let the system provide */
/* a timeout for us with very little CPU usage. */
/*--------------------------------------------------------------------*/
unsigned int nsread(char *output, unsigned int wanted, unsigned int timeout)
{
APIRET rc;
static char save[MAXPACK];
static USHORT bufsize = 0;
time_t stop_time ;
time_t now ;
USHORT com_error;
#ifdef __OS2__
ULONG ParmLengthInOut;
ULONG DataLengthInOut;
#endif
/*--------------------------------------------------------------------*/
/* Determine if our internal buffer has the data */
/*--------------------------------------------------------------------*/
if (bufsize >= wanted)
{
memmove( output, save, wanted );
bufsize -= wanted;
if ( bufsize ) /* Any data left over? */
memmove( save, &save[wanted], bufsize ); /* Yes --> Save it*/
return wanted + bufsize;
} /* if */
/*--------------------------------------------------------------------*/
/* Reset any errors on the communications port */
/*--------------------------------------------------------------------*/
#ifdef __OS2__
ParmLengthInOut = 0;
DataLengthInOut = sizeof(com_error);
rc = DosDevIOCtl( com_handle,
IOCTL_ASYNC,
ASYNC_GETCOMMERROR,
NULL,
0L,
&ParmLengthInOut,
(PVOID) &com_error,
sizeof(com_error),
&DataLengthInOut);
#else
rc = DosDevIOCtl( &com_error,
FAR_NULL,
ASYNC_GETCOMMERROR ,
IOCTL_ASYNC,
com_handle);
#endif
if (rc )
{
printmsg(0,"nsread: Unable to read port errors");
printOS2error( "DosDevIOCtl", rc );
} /*if */
else if ( com_error )
ShowError( com_error );
/*--------------------------------------------------------------------*/
/* Determine when to stop processing */
/*--------------------------------------------------------------------*/
if ( timeout == 0 )
{
stop_time = 0;
now = 1; /* Any number greater than stop time */
}
else {
time( & now );
stop_time = now + timeout;
}
/*--------------------------------------------------------------------*/
/* Try to read any needed data into the buffer */
/*--------------------------------------------------------------------*/
do {
USHORT needed = (USHORT) wanted - bufsize;
USHORT port_timeout;
#ifdef __OS2__
ULONG received = 0;
#else
USHORT received = 0;
#endif
/*--------------------------------------------------------------------*/
/* Handle an aborted program */
/*--------------------------------------------------------------------*/
if ( raised )
return 0;
if ( terminate_processing )
{
static boolean recurse = FALSE;
if ( ! recurse )
{
printmsg(2,"nsread: User aborted processing");
recurse = TRUE;
}
return 0;
}
/*--------------------------------------------------------------------*/
/* Compute a new timeout for the read, if needed */
/*--------------------------------------------------------------------*/
if (stop_time > now )
{
port_timeout = (USHORT) (stop_time - now) / needed * 100;
if (port_timeout < 100)
port_timeout = 100;
}
else
port_timeout = 0;
if ( port_timeout != com_dcbinfo.usReadTimeout )
{
com_dcbinfo.usReadTimeout = port_timeout;
#ifdef __OS2__
ParmLengthInOut = sizeof(com_dcbinfo);
DataLengthInOut = 0;
rc = DosDevIOCtl( com_handle,
IOCTL_ASYNC,
ASYNC_SETDCBINFO,
(PVOID) &com_dcbinfo,
sizeof(com_dcbinfo),
&ParmLengthInOut,
NULL,
0L,
&DataLengthInOut);
#else
rc = DosDevIOCtl(FAR_NULL,
&com_dcbinfo,
ASYNC_SETDCBINFO,
IOCTL_ASYNC,
com_handle);
#endif
if ( rc )
{
printmsg(0,"nsread: Unable to set timeout for comm port");
printOS2error( "DosDevIOCtl", rc );
panic();
} /* if */
} /* if */
#ifdef UDEBUG
printmsg(15,"nsread: Port time out is %ud seconds/100",
port_timeout);
#endif
/*--------------------------------------------------------------------*/
/* Read the data from the serial port */
/*--------------------------------------------------------------------*/
rc = DosRead( com_handle, &save[bufsize], needed, &received );
if ( rc == ERROR_INTERRUPT)
{
printmsg(2,"Read Interrupted");
return 0;
}
else if ( rc != 0 )
{
printmsg(0,"nsread: Read from comm port for %d bytes failed.",
needed);
printOS2error( "DosRead", rc );
bufsize = 0;
return 0;
}
#ifdef UDEBUG
printmsg(15,"nsread: Want %d characters, received %d, total %d in buffer",
(int) wanted, (int) received, (int) bufsize + received);
#endif
/*--------------------------------------------------------------------*/
/* Log the newly received data */
/*--------------------------------------------------------------------*/
traceData( &save[bufsize], received, FALSE );
/*--------------------------------------------------------------------*/
/* If we got the data, return it to the caller */
/*--------------------------------------------------------------------*/
bufsize += received;
if ( bufsize == wanted )
{
memmove( output, save, bufsize);
bufsize = 0;
if (debuglevel > 14)
fwrite(output,1,bufsize,stdout);
return wanted;
} /* if */
/*--------------------------------------------------------------------*/
/* Update the clock for the next pass */
/*--------------------------------------------------------------------*/
if (stop_time > 0)
time( &now );
} while (stop_time > now);
/*--------------------------------------------------------------------*/
/* We don't have enough data; report what we do have */
/*--------------------------------------------------------------------*/
return bufsize;
} /*nsread*/
/*--------------------------------------------------------------------*/
/* n s w r i t e */
/* */
/* Write to the serial port */
/*--------------------------------------------------------------------*/
int nswrite(const char *input, unsigned int len)
{
char *data = (char *) input;
#ifdef __OS2__
ULONG bytes;
#else
size_t bytes;
#endif
APIRET rc;
hangupNeeded = TRUE; /* Flag that the port is now dirty */
/*--------------------------------------------------------------------*/
/* Write the data out as the queue becomes available */
/*--------------------------------------------------------------------*/
rc = DosWrite( com_handle, data , len, &bytes);
if (rc)
{
printOS2error( "DosWrite", rc );
return bytes;
} /*if */
/*--------------------------------------------------------------------*/
/* Log the data written */
/*--------------------------------------------------------------------*/
traceData( data, len, TRUE);
/*--------------------------------------------------------------------*/
/* Return bytes written to the port to the caller */
/*--------------------------------------------------------------------*/
return len;
} /* nswrite */
/*--------------------------------------------------------------------*/
/* n s s e n d b r k */
/* */
/* send a break signal out the serial port */
/*--------------------------------------------------------------------*/
void nssendbrk(unsigned int duration)
{
#ifdef __OS2__
ULONG ParmLengthInOut;
ULONG DataLengthInOut;
#endif
USHORT com_error;
#ifdef UDEBUG
printmsg(12, "ssendbrk: %d", duration);
#endif
#ifdef __OS2__
ParmLengthInOut = 0;
DataLengthInOut = sizeof(com_error);
DosDevIOCtl( com_handle,
IOCTL_ASYNC,
ASYNC_SETBREAKON,
NULL,
0L,
&ParmLengthInOut,
(PVOID) &com_error,
sizeof(com_error),
&DataLengthInOut);
#else
DosDevIOCtl( &com_error,
FAR_NULL,
ASYNC_SETBREAKON,
IOCTL_ASYNC,
com_handle);
#endif
if ( com_error )
ShowError( com_error );
ddelay( duration == 0 ? 200 : duration);
#ifdef __OS2__
ParmLengthInOut = 0;
DataLengthInOut = sizeof(com_error);
DosDevIOCtl( com_handle,
IOCTL_ASYNC,
ASYNC_SETBREAKOFF,
NULL,
0L,
&ParmLengthInOut,
(PVOID) &com_error,
sizeof(com_error),
&DataLengthInOut);
#else
DosDevIOCtl( &com_error,
FAR_NULL,
ASYNC_SETBREAKOFF,
IOCTL_ASYNC,
com_handle);
#endif
if ( com_error )
ShowError( com_error );
} /*nssendbrk*/
/*--------------------------------------------------------------------*/
/* n c l o s e l i n e */
/* */
/* Close the serial port down */
/*--------------------------------------------------------------------*/
void ncloseline(void)
{
APIRET rc;
USHORT com_error;
#ifdef __OS2__
ULONG ParmLengthInOut;
ULONG DataLengthInOut;
#endif
if ( ! portActive )
{
printmsg(0,"ncloseline: Internal error, port already closed");
return;
}
portActive = FALSE; /* flag port closed for error handler */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -