home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************
- * XON_XOFF.CPP - Listing 4
- * Written by Kevin D. Weeks, August 1990
- * Compiles and runs under Borland Turbo C++ and Zortech C++.
- */
- #include <stdio.h>
- #include "xon_xoff.hpp"
- // handshake function codes
- #define RECV_TEST 1
- #define SEND_TEST 2
- #define BUF_EMPTY 3
- #define XON 17
- #define XOFF 19
- int xon_xoff_handler(int function_code);
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * This method replaces Serial_Comm's open to allow for setting the
- * hand-shaking function. */
- Result Xon_Xoff::open(void)
- {
- // make sure no one else has the com port, then set hand-shaking
- // and call Serial_Comm to open the port
- if (open_flag == NULL) {
- com_set_handshake(xon_xoff_handler);
- return Serial_Comm::open();
- }
- return ERROR;
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * This method replaces Serial_Comm's close to allow for re-setting
- * the hand-shaking function. */
- void Xon_Xoff::close(void)
- {
- if (open_flag == this || open_flag == NULL) {
- com_set_handshake(NULL);
- Serial_Comm::close();
- }
- }
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * This is the function that actually performs hand-shaking. Although
- * the assembly routines are coded to support calls to C functions,
- * it is usually better practice to code this function in assembler
- * so that it operates as fast as possible.
- * The high byte of function_code contains the actual function code
- * from the assembly routine.The low byte of the function code
- * contains either the byte received or the byte to be sent. */
- #pragma option -N- // turn off stack checking
- int xon_xoff_handler(int function_code)
- {
- // state flags
- static Bool send_xoff = FALSE;
- static Bool send_xon = FALSE;
- static Bool sending_halted = FALSE;
- static Bool xoff_sent = FALSE;
- Comm_Status stat;
- switch (function_code >> 8) { // determine function code
- case RECV_TEST:
- stat.value = com_get_status();
- // turn off receiving if there are less than 64 bytes still
- // free in the receive buffer
- if (com_chars_recvd() > 960)
- if (stat.flag.sending_message)
- send_xoff = TRUE;
- else {
- xoff_sent = TRUE;
- com_write_char(XOFF);
- }
- if ((function_code & 0x00ff) == XOFF)
- // if XOFF received then stop sending
- if (stat.flag.sending_message) {
- com_stop_sending();
- sending_halted = TRUE;
- return 0xff00;
- }
- if ((function_code & 0x00ff) == XON)
- // if XON received then start sending
- if (sending_halted) {
- com_start_sending();
- sending_halted = FALSE;
- return 0xff00;
- }
- // clear high byte so the character will be saved
- return (function_code & 0x00ff);
- case SEND_TEST:
- if (send_xon) {
- send_xon = FALSE;
- xoff_sent = FALSE;
- return (0xff00 | XON);
- }
- if (send_xoff) {
- send_xoff = FALSE;
- xoff_sent = TRUE;
- return (0xff00 | XOFF);
- }
- // clear high byte so send_tail will be incremented
- return (function_code & 0x00ff);
- case BUF_EMPTY:
- stat.value = com_get_status();
- if (xoff_sent)
- // if sending was stopped then restart it
- if (stat.flag.sending_message)
- send_xon = TRUE;
- else {
- com_write_char(XON);
- xoff_sent = FALSE;
- }
- return 0;
- };
- }
- #pragma option -N+ // turn stack checking back on
-