home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
comm
/
bye_pc1.zip
/
BYEXFACE.C
< prev
next >
Wrap
Text File
|
1987-01-03
|
13KB
|
523 lines
/*
** Program: <byexface.c>
**
** Author: R.E. Starr, Jr. (10/20/86)
**
** Revisons:
**
** (10/20/86) 1.00 - First release
** (11/01/86) 1.01 - added timeout return status in mdm_putc().
** (12/20/86) 1.02 - corrected modem get_char() error return.
** requires BYE-PC version 1.02 or greater.
**
** Purpose: Provides interface functions to BYE-PC interrupt 66h
** for access to the modem controls and status.
**
** Requirments: This code will compile directly using the MSC 3.1
** compiler. It can be compiled in any of the memory
** models supported by MSC. Once compiled, link the object
** code with the application modules to add BYE-PC inter-
** face capabilty to 'C' programs. This code is intended
** to simplify access to XMODEM and RBBS programs written
** to work with BYE-PC.
**
*/
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <process.h>
#include <time.h>
#include <ctype.h>
#include "byexface.h"
#define BYE_VECT 0x66 /* BYE access interrupt vector */
#define YES 1
#define NO 0
#define ON 1
#define OFF 0
/*
** Function: int check_bye(lver, hver, lrev, hrev)
**
** Parms: int lver = lowest version# acceptable
** int hver = highest version# acceptable
** int lrev = lowest revision# acceptable
** int hrev = highest revision# acceptable
**
** Purpose: Test to see if BYE-PC is loaded before executing
** any other functions. Prevents a system crash!!!
** If you call any other functions that call BYE-PC
** interrupt 66h, before 'check_bye() == 1' the system
** will crash. The interrupt vectors are uninitialized
** and contain null or garbage data. This checks to
** make sure that BYE-PC has been loaded.
**
** Return: 0 = BYE-PC loaded and is acceptable version/revision
** 1 = BYE-PC is not loaded yet
** 2 = BYE-PC is loaded but, invalid version#
** 3 = BYE-PC is loaded but, invalid revision#
**
*/
int check_bye(lver, hver, lrev, hrev)
int lver, hver, lrev, hrev;
{
char c;
char far *addr;
int ver, rev;
unsigned long x;
union REGS inregs, outregs;
struct SREGS segregs;
inregs.h.ah = 0x35; /* DOS get vector function */
inregs.h.al = 0x16;
int86x(0x21, &inregs, &outregs, &segregs);
x = (long)segregs.es;
addr = (char far *)(x << 16 | 0x00000103L);
if (*addr++ != 'B') /* look for title in code */
return(1); /* that interrupt vector */
else if (*addr++ != 'Y') /* is pointing to. */
return(1);
else if (*addr++ != 'E')
return(1);
x = bye_vers();
ver = (int)(x >> 8); /* get version number */
rev = (int)(x & 0x00FF); /* get revison level */
if (ver < lver || ver > hver) /* version# accpeptable */
return(2); /* assume we found BYE-PC */
if (rev < lrev || rev > hrev) /* revision# accpeptable */
return(3); /* return version error */
return(0); /* all was ok */
}
/*
** Function: unsigned mdm_getc()
**
** Purpose: Return character from the modem Rx-queue if available.
** The function 'rx_size()' can be used to determine if
** data is available in the Rx-queue.
**
** Return: EOF if no character in buffer
**
*/
unsigned mdm_getc()
{
int c;
union REGS inregs, outregs;
inregs.h.al = 0; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((unsigned)outregs.x.ax); /* character in lsb */
}
/*
** Function: int mdm_putc()
**
** Purpose: Send the character to the modem via BYE-PC. Note
** that if nulls are in effect that these will not be
** sent a line feed character. The user must handle any
** nulls that are needed by 'get_nulls()'.
**
** Return: EOF = timeout error
** 0 = Tx ok
**
*/
int mdm_putc(c)
int c;
{
union REGS inregs, outregs;
inregs.h.al = 1; /* load BYE function# */
inregs.h.ah = (char)c; /* load character to send */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((int)outregs.x.ax); /* character in lsb */
}
/*
** Function: void mdm_dtr(flag)
**
** Parms: flag = 1 DTR/CTS line ON
** flag = 0 DTR/CTS line OFF
**
** Purpose: Toggle the DTR line on the modem to hangup. If the
** carrier detect status is enabled, the system will
** hangup and re-boot if this is called with dtr off.
** The function 'set_cd()' should be used to prevent
** this is needed.
**
** Return: <none>
**
*/
void mdm_dtr(flag)
int flag;
{
union REGS regs;
regs.h.al = 2; /* load BYE function# */
regs.h.ah = (char)flag; /* load character to send */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: int mdm_cd()
**
** Purpose: Test for carrier detect status from the modem.
** Returns a logical TRUE if the modem still has
** caller on line with carrier.
**
** Return: 1 = Carrier Detect found
** 0 = Carrier Detect not found
**
*/
int mdm_cd()
{
union REGS inregs, outregs;
inregs.h.al = 3; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((int)outregs.x.ax); /* return Rx-queue size */
}
/*
** Function: void set_cd(flag)
**
** Parms: flag = 0 carrier check disabled
** flag = 1 carrier check enabled
**
** Purpose: Sets a flag in BYE-PC to ignore carrier detect
** status. This is used before writing to a file to
** prevent warm booting while writing to disk in the
** event carrier is lost during disk writes.
**
*/
void set_cd(flag)
int flag;
{
union REGS regs;
regs.h.al = 4; /* load BYE function# */
regs.h.ah = (char)flag; /* load character to send */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: void rx_flush()
**
** Purpose: Removes characters waiting in the Rx-queue and
** resets the Rx-character counter to 0. This is
** used to reset after a buffer overflow and before
** starting any data transfers to remove any trash
** from the Rx-queue.
**
** Return: <none>
**
*/
void rx_flush()
{
union REGS regs;
regs.h.al = 5; /* load BYE function# */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: int rx_size()
**
** Purpose: Test for characters waiting in the Rx-queue and
** returns the number of characters in the queue. If
** 'size' is > 0 and 'mdm_getch()' returns and EOF,
** a buffer overflow occured and 'rx_flush' must be
** called to reset counts.
**
** Return: Returns the number of characters in the Rx-queue
**
*/
int rx_size()
{
union REGS inregs, outregs;
inregs.h.al = 6; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((int)outregs.x.ax); /* return Rx-queue size */
}
/*
** Function: int mdm_baud()
**
** Purpose: Returns the baud rate of the caller on line.
**
** Return: 0 = 300 bps
** 1 = 1200 bps
** 2 = 2400 bps
**
*/
int mdm_baud()
{
union REGS inregs, outregs;
inregs.h.al = 7; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((int)outregs.x.ax); /* return Rx-queue size */
}
/*
** Function: void set_break(flag)
**
** Parms: flag =
**
** CTRL_NOBRK = 0 remote ^C & ^S break disabled
** CTRL_BRK = 1 remote ^C & ^S break enabled
** CTRL_NOTOUT = 2 remote ^S timeout disabled
** CTRL_TOUT = 3 remote ^S timeout enabled
** CTRL_NOTRAP = 4 dont filter out ^C & ^S chars
** CTRL_TRAP = 5 allow filter of ^C & ^S chars
**
** Purpose: This sets the control/break pause flag for the
** remote caller only! The local console still has
** control over breaks/pauses.
**
*/
void set_break(flag)
int flag;
{
union REGS regs;
regs.h.al = 8; /* load BYE function# */
regs.h.ah = (char)flag; /* load character to send */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: int rx_state(flag)
**
** Parms: flag = 1 Rx-chars from mdm ignored during keybd input
** flag = 0 Rx-chars from mdm sent to keybd input
**
** Purpose: This is used to temporarily toggle the input from
** the remote station on/off. The rx-queue is still active
** and continues to collect data while off. An rx-overflow
** can ocuur. Users should call Rx-flush before re-starting
** 'rx_state()' to ON.
**
*/
void rx_state(flag)
int flag;
{
union REGS regs;
regs.h.al = 9; /* load BYE function# */
regs.h.ah = (char)flag; /* load character to send */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: void tx_state(flag)
**
** Parms: flag = 1 Chars written to console are sent
** flag = 0 Chars written to console are not sent
**
** Purpose: This turns off the output to the remote end temporarily.
** Data written to the screen will not be sent if the
** tx_state is off. This allows writting the local screen
** without the output going to the remote end.
**
*/
void tx_state(flag)
int flag;
{
union REGS regs;
regs.h.al = 10; /* load BYE function# */
regs.h.ah = (char)flag; /* load character to send */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: unsigned bye_vers()
**
** Purpose: Returns the currnet version# of BYE-PC running.
**
** Return: LSB = Revision Number
** MSB = Version Number
**
*/
unsigned bye_vers()
{
union REGS inregs, outregs;
inregs.h.al = 11; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((unsigned)outregs.x.ax); /* return version number */
}
/*
** Function: int get_nulls()
**
** Purpose: Returns the # nulls sent after each LF char.
**
*/
int get_nulls()
{
union REGS inregs, outregs;
inregs.h.al = 12; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return((int)outregs.x.ax); /* return # of nulls */
}
/*
** Function: void set_nulls(x)
**
** Parms: int x = (0 to 9)
**
** Purpose: Sets the # nulls sent after each LF char.
**
*/
void set_nulls(x)
int x;
{
union REGS regs;
regs.h.al = 13; /* load BYE function# */
regs.h.ah = (char)x; /* load # of nulls */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** Function: void warm_boot()
**
** Parms: <none>
**
** Purpose: Hangs up the modem and re-boots system. Used by
** XMDM and RBBS mainly.
**
*/
void warm_boot()
{
union REGS regs;
mdm_cd(OFF); /* disable carrier detect */
mdm_dtr(OFF); /* now hangup the modem */
regs.h.al = 14; /* load BYE function# */
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}
/*
** The caller status word is a sixteen bit word used by SHELL, XMDM,
** and other application programs to check for command priorities which
** are set by an RBBS program before the user can enter DOS. The MSW of
** the status word bits have been reserved for any applications that
** may be developed in the future. The LSW bits have the followine
** meaning:
**
** CSW (Caller status word):
**
** {LSW (least significant word)}
**
** ----MSB---- ----LSB----
** D7 D6 D5 D4 D3 D2 D1 D0
** | | | | | | |---|--- Max Drive allowed.
** | | | | | |---------- PATH command allowed.
** | | | | |------------- CD command allowed.
** | | | |----------------- XMDM S {file} allowed.
** | | |-------------------- XMDM R {file} allowed.
** | |----------------------- Shell DOS command allowed.
** |-------------------------- Shell EXIT command allowed.
**
**
** {MSW (most significant word)}
**
** ----MSB---- ----LSB----
** D7 D6 D5 D4 D3 D2 D1 D0 Reserved for
** {unused} {unused} Future application programs
**
**
*/
/*
** Function: int get_cstat()
**
** Parms: <none>
**
** Purpose: Returns the status level from BYE-PC of caller
** currently on line.
**
*/
int get_cstat()
{
union REGS inregs, outregs;
inregs.h.al = 15; /* load BYE function# */
int86(BYE_VECT, &inregs, &outregs); /* perform BYE-PC call INT 66h */
return(outregs.x.ax);
}
/*
** Function: int set_cstat(s)
**
** Parms: int s; caller status level (0-ffffh)
**
** Purpose: Set the status level in BYE-PC for the caller
** currently on line.
**
*/
void set_cstat(s)
int s;
{
union REGS regs;
regs.h.al = 16; /* load BYE function# */
regs.x.cx = s;
int86(BYE_VECT, ®s, ®s); /* perform BYE-PC call INT 66h */
}