home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
CALLF.ZIP
/
FOSSIL.C
< prev
Wrap
C/C++ Source or Header
|
1988-07-08
|
9KB
|
283 lines
#include <dos.h>
void set_baud_rate(int, int);
int request_status(int);
int initialize_driver(int);
void deinitialize_driver(int);
void raise_lower_dtr(int, int);
void flush_output_buffer(int);
void flow_control(int, int);
int read_block(int, char *, int);
int write_block(int, char *, int);
union REGS regs;
/*
** Set baud rate
**
** Input: AH = 00H
** AL = baud rate code
** DX = port number
**
** This works the same as the equivalent IBM PC BIOS call, except that it
** ONLY selects a baud rate. This is passed in the high order 3 bits of AL
** as follows:
**
** 010 = 300 baud
** 011 = 600 ''
** 100 = 1200 ''
** 101 = 2400 ''
** 110 = 4800 ''
** 111 = 9600 ''
** 000 = 19200 '' (Replaces old 110 baud mask)
** 001 = 38400 '' (Replaces old 150 baud mask)
**
** The low order 5 bits can be implemented or not by the FOSSIL, but in all
** cases, if the low order bits of AL are 00011, the result should be that
** the communications device should be set to eight data bits, one stop bit
** and no parity. This setting is a MINIMUM REQUIREMENT of Fido, Opus and
** SEAdog. For purposes of completeness, here are the IBM PC "compatible"
** bit settings:
**
** Bits 4-3 define parity: 0 0 no parity
** 1 0 no parity
** 0 1 odd parity
** 1 1 even parity
**
** Bit 2 defines stop bits: 0 1 stop bit;
** 1 1.5 bits for 5-bit char;
** 2 for others
**
** Bits 1-0 character length: 0 0 5 bits
** 0 1 6 bits
** 1 0 7 bits
** 1 1 8 bits
*/
void set_baud_rate(port, baud_rate_code)
int port, baud_rate_code;
{
regs.h.ah = 0x00;
regs.h.al = baud_rate_code;
regs.x.dx = port;
int86(0x14, ®s, ®s);
}
/*
** Request status
**
** Input: AH = 03H
** DX = port number
** Output: AX = status bit mask (see below)
**
** Returns with the line and modem status in AX. Status bits returned are:
**
** In AH:
** Bit 0 = RDA - input data is available in buffer
** Bit 5 = THRE - room is available in output buffer
** Bit 6 = TSRE - output buffer is empty
**
** In AL:
** Bit 7 = DCD - carrier detect
**
** This can be used by the application to determine whether carrier detect
** (CD) is set, signifying the presence/absence of a remote connection, as
** well as monitoring both the input and output buffer status.
*/
int request_status(port)
int port;
{
regs.h.ah = 0x03;
regs.x.dx = port;
int86(0x14, ®s, ®s);
return (regs.x.ax);
}
/*
** Initialize driver
**
** Input: AH = 04H
** DX = port number
** ( BX = 4F50H
** CX = ^C flag address --- optional )
** Output: AX = 1954H if successful
** BL = maximum function number supported
** (not counting functions 7E and above)
** BH = rev of FOSSIL doc supported
**
** This is used to tell the driver to begin operations, and to check that
** the driver is installed. This function should be called before any other
** communications calls are made. At this point all interrupts involved in
** supporting the comm port (specified in DX) should be set up for handling
** by the FOSSIL, then enabled. If BX contains 4F50 hex, then the address
** specified in BX:CX is that of a ^C flag byte in the application program,
** to be incremented when ^C is detected in the keyboard service routines.
** This is an optional service and only need be supported on machines where
** the keyboard service can't (or won't) perform an INT 1B or INT 23 when a
** Control-C is entered. DTR is raised by this call.
**
** NOTE: Should an additional call to this service occur (2 Inits or Init,
** Read,Init, etc.) the driver should reset all buffers, flow control, etc.
** to the INIT state and return SUCCESS.
*/
int initialize_driver(port)
int port;
{
regs.h.ah = 0x04;
regs.x.dx = port;
regs.x.bx = 0;
int86(0x14, ®s, ®s);
if (regs.x.ax == 0x1954)
return(regs.h.bl); /* return number of fuctions */
else
return(0);
}
/*
** Deinitialize driver
**
** Input: AH = 05H
** DX = port number
**
** This is used to tell the driver that comm port operations are ended. The
** function should be called when no more comm port functions will be used
** on the port specified in DX. DTR is NOT affected by this call.
*/
void deinitialize_driver(port)
int port;
{
regs.h.ah = 0x05;
regs.x.dx = port;
int86(0x14, ®s, ®s);
}
/*
** Raise/lower DTR
**
** Input: AH = 06H
** DX = port number
** AL = DTR state to be set (1 = Raise, 0 = Lower)
**
** This function is used to control the DTR line to the modem. AL = 0 means
** lower DTR (disable the modem), and AL = 1 means to raise DTR (enable the
** modem). No other function (except Init) should alter DTR.
*/
void raise_lower_dtr(port, dtr)
int port, dtr;
{
regs.h.ah = 0x06;
regs.h.al = dtr;
regs.x.dx = port;
int86(0x14, ®s, ®s);
}
/*
** Flush output buffer
**
** Input: AH = 08H
** DX = port number
**
** This is used to force any pending output. It does not return until all
** pending output has been sent. You should use this call with care. Flow
** control (documented below) can make your system hang on this call in a
** tight uninterruptible loop under the right circumstances.
*/
void flush_output_buffer(port)
int port;
{
regs.h.ah = 0x08;
regs.x.dx = port;
int86(0x14, ®s, ®s);
}
/*
** Enable or Disable flow control on transmit
**
** Input: AH = 0FH
** AL = bit mask describing requested flow control
** DX = port number
**
** This is used to stop output when the "other end" is overwhelmed, or when
** a BBS user wants to stop a screen.
**
** Two kinds of flow control are supported:
**
** Bit 0 = 1 Enable Receiving of XON/XOFF
** Bit 1 = 1 CTS/RTS
** Bit 2 is Reserved
** Bit 3 = 1 Enable Sending of XON/XOFF
**
** Flow control is enabled, or disabled, by setting the appropriate bits in
** AL for the types of flow control we want to ENABLE (value = 1), and/or
** DISABLE (value = 0), and calling this function. Bit 2 is reserved for
** DSR/DTR but is not currently supported in any implementation.
**
** Applications using this function should set all bits ON in the high
** nibble of AL as well. There is a compatible (but not identical) FOSSIL
** driver implementation that uses the high nibble as a control mask. If
** your application sets the high nibble to all ones, it will always work,
** regardless of the method used by any given driver.
*/
void flow_control(port, bits)
int port, bits;
{
regs.h.ah = 0x0f;
regs.h.al = bits;
regs.x.dx = port;
int86(0x14, ®s, ®s);
}
/*
** Read block (transfer from FOSSIL to user buffer)
**
** Input: AH = 18H
** CX = maximum number of characters to transfer
** DX = port number
** ES = segment of user buffer
** DI = offset into DS of user buffer
** Output: AX = number of characters actually transferred
**
** A "no-wait" block read of 0 to 0xffff characters from the FOSSIL inbound
** ring buffer to the calling routine's buffer. DS:SI are left untouched by
** the call; the count of bytes actually transferred will be in AX.
*/
int read_block(port, ptr, len)
int port, len;
char *ptr;
{
regs.h.ah = 0x18;
regs.x.dx = port;
regs.x.di = (int) ptr;
regs.x.cx = len;
int86(0x14, ®s, ®s);
return (regs.x.ax);
}
/*
** Write block (transfer from user buffer to FOSSIL)
**
** Input: AH = 19H
** CX = maximum number of characters to transfer
** DX = port number
** ES = segment of user buffer
** DI = offset into DS of user buffer
** Output: AX = number of characters actually transferred
**
** A "no-wait" block move of 0 to 0xffff characters from the calling
** program's buffer into the FOSSIL outbound ring buffer. The actual number
** of characters moved into the ring buffer will be returned in AX.
*/
int write_block(port, ptr, len)
int port, len;
char *ptr;
{
regs.h.ah = 0x19;
regs.x.dx = port;
regs.x.di = (int) ptr;
regs.x.cx = len;
int86(0x14, ®s, ®s);
return (regs.x.ax);
}