📄 ulibfs.c
字号:
/*--------------------------------------------------------------------*/
/* u l i b f s . c */
/* */
/* UUPC/extended communications driver for MS-DOS FOSSIL */
/* based systems. */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* 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: ulibfs.c 1.3 1993/10/03 22:09:09 ahd Exp $
*
* History:
* $Log: ulibfs.c $
* Revision 1.3 1993/10/03 22:09:09 ahd
* Use unsigned long to display speed
*
* Revision 1.2 1993/05/30 15:25:50 ahd
* Multiple driver support
*
* Revision 1.1 1993/05/30 00:01:47 ahd
* Initial revision
*
*/
/*--------------------------------------------------------------------*/
/* System include files */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h> // For memset()
#include <stdlib.h> // For max()
#include <dos.h> // For FOSSIL interrupt calls
#include <time.h> // For sleep.h support
/*--------------------------------------------------------------------*/
/* UUPC/extended include files */
/*--------------------------------------------------------------------*/
#include "lib.h"
#include "ulibfs.h"
#include "commlib.h"
#include "fossil.h"
#include "catcher.h" // For terminate processing flags
#include "ssleep.h" // For ddelay, etc.
/*--------------------------------------------------------------------*/
/* Internal prototypes */
/*--------------------------------------------------------------------*/
static void showModem( const short );
static void getDriverInfo( FS_INFO *fossilData);
static short blockIO( char *buffer,
const short len,
const char function);
/*--------------------------------------------------------------------*/
/* Global variables */
/*--------------------------------------------------------------------*/
static BPS currentBPS;
static boolean currentDirect;
static boolean carrierDetect;
static boolean hangupNeeded;
currentfile();
/*--------------------------------------------------------------------*/
/* f o p e n L i n e */
/* */
/* Open a fossil controlled port */
/*--------------------------------------------------------------------*/
int fopenline(char *name, BPS baud, const boolean direct)
{
short result;
FS_INFO fossilData; // Information returned by FOSSIL
/*--------------------------------------------------------------------*/
/* Determine the port number */
/*--------------------------------------------------------------------*/
if (sscanf(name, "COM%d", &portNum) != 1)
{
printmsg(0,"Communications port must be format COMx, was %s",
name);
panic();
}
portNum--; // FOSSIL uses offset, not ordinal number
/*--------------------------------------------------------------------*/
/* Attempt to initialize the driver */
/*--------------------------------------------------------------------*/
result = FSOpen( ); // Try to open the port
if ( result != FS_COOKIE )
{
printmsg(0,"fopenLine: Open failed, result %d",result );
return TRUE; // Report failure
}
/*--------------------------------------------------------------------*/
/* Now initialize the rest of the port information */
/*--------------------------------------------------------------------*/
ssleep(2); // Wait two seconds as required by V.24
currentDirect = direct; // Save for flow control processing
carrierDetect = FALSE; // No modem connected yet
flowcontrol( FALSE ); // Set no (or hardware) flow control
fSIOSpeed( baud ); // Set the port speed
traceStart( name ); // Enable line tracing
getDriverInfo( &fossilData );
printmsg(4,"fopenline: Driver: %Fs (revision %d)",
fossilData.id,
(int) fossilData.revision );
printmsg(4,"fopenline: FOSSIL version %d, "
"input buffer %d, output buffer %d",
(int) fossilData.version,
(int) fossilData.inputSize,
(int) fossilData.outputSize );
portActive = TRUE; // Flag port is open
return FALSE; // Report success to caller
} /* fopenLine */
/*--------------------------------------------------------------------*/
/* f s r e a d */
/* */
/* Read a specified number of bytes from the serial port */
/*--------------------------------------------------------------------*/
unsigned int fsread(char *buffer,
unsigned int wanted,
unsigned int timeout)
{
FS_INFO fossilData; // Information returned by FOSSIL
time_t quit = time( NULL ) + timeout;
showModem( FSStatus()); // Report modem status if changed
/*--------------------------------------------------------------------*/
/* Main loop to read data from FOSSIL */
/*--------------------------------------------------------------------*/
for ( ;; )
{
unsigned int pending;
getDriverInfo( &fossilData );
pending = fossilData.inputSize - fossilData.inputFree;
if ( pending >= wanted )
{
unsigned int moved = blockIO( buffer, wanted, FS_READBLOK );
// Get the data
traceData( buffer, moved, FALSE ); // Trace the data
if ( moved < wanted) // Promised data delivered?
{ // NO --> Panic (literally)
printmsg(0,"fsread: Read failed at %d of %d bytes"
"(%d bytes available)",
moved,
wanted,
pending );
panic();
}
return pending; // Return success
} /* if ( pending >= wanted ) */
/*--------------------------------------------------------------------*/
/* We don't have the data we need (yet), see if we can wait */
/* for it. */
/*--------------------------------------------------------------------*/
if (quit <= time(NULL)) // Any time left to wait?
{
printmsg(20, "fsread: pending=%d, wanted=%d",
pending, wanted);
return pending; // No --> return quietly
}
if ( terminate_processing ) // User hit Ctrl-Break?
{
static boolean recurse = FALSE;
if ( ! recurse )
{
printmsg(2,"fsread: User aborted processing");
recurse = TRUE;
}
return 0;
} /* if ( terminate_processing ) */
if ( fossilData.inputSize < (int) wanted ) // Sanity check this ...
{ // last for performance reasons.
printmsg(0,"fsread: FOSSIL queue too small (%d bytes) to"
"satisfy read of %d bytes",
fossilData.inputSize , wanted );
panic();
} /* if */
ddelay(0); // Pause, then do it all again
} /* for ( ;; ) */
} /* fsread */
/*--------------------------------------------------------------------*/
/* f s w r i t e */
/* */
/* Write data to a FOSSIL controled serial port */
/*--------------------------------------------------------------------*/
int fswrite(const char *data, unsigned int queued)
{
int moved;
int total;
int spin;
static int const max_spin = 20;
FS_INFO fossilData; // Information returned by FOSSIL
hangupNeeded = TRUE; // Serial port is now "dirty"
showModem( FSStatus()); // Report modem status if changed
/*--------------------------------------------------------------------*/
/* Perform the I/O */
/*--------------------------------------------------------------------*/
moved = blockIO( (char *) data, queued, FS_WRITBLOK );
// Write the data to port
traceData( data, moved, TRUE); // Trace our output
if ( moved == (int) queued ) // Did it all get written out?
return moved; // Yes --> Return gracefully
printmsg(4,"fswrite: Wrote %d bytes of %d", moved, queued);
/*--------------------------------------------------------------------*/
/* The FOSSIL driver didn't have enough room in its buffer; */
/* determine how much we did send. */
/*--------------------------------------------------------------------*/
getDriverInfo( &fossilData );
total = moved;
queued -= moved; // We only need to still move this
/*--------------------------------------------------------------------*/
/* Block processing for a limited amount of time if we need */
/* more room in the FOSSIL buffer. */
/*--------------------------------------------------------------------*/
spin = max_spin;
while( spin && queued )
{
int wait;
int needed;
needed = max(fossilData.outputSize / 2, (int) queued );
/* Minimize thrashing by requiring
big chunks */
wait = (int) ((long) needed * 10000L / (long) currentBPS);
/* Compute time in milliseconds
assuming 10 bits per byte */
printmsg(4,"fswrite: Waiting %d ms for %d bytes in queue"
", pass %d",
wait, needed, spin);
ddelay( wait ); /* Actually perform the wait */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -