home *** CD-ROM | disk | FTP | other *** search
- /*
- ** 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 */
- }
-
-
-