/* Copyright (C) Magna Carta Software, Inc. 1990, 1991. All Rights Reserved. C COMMUNICATIONS TOOLKIT TXXLAT.C -- Transmission with data transformation. */ #define CCT_DEVELOPMENT #include #include #include #define xlat_tx(x) p->a_tx_xlat[(short) (x)] /* C_FLUSH_TX_ -- Send any pending bytes out of a port. Return value: 0 -- byte sent; EOF -- no bytes pending; < 0 -- return code from c_putc(); */ static short NEAR_ c_flush_tx_(COMM_PORT *p) { short ret = EOF; if (p->tx_f_lastchar) { p->tx_f_lastchar = FALSE; ret = c_putc(p, p->tx_lastchar); } return (ret); } /* C_PUTC -- Send a character out of the designated port. Use data translation if it is enabled. Return value: 0 -- normal return; RX_TIMEOUT -- expected echo not received from remote system; */ short c_putc(COMM_PORT *p, short ch) { short f_tx = TRUE, c, ch1; #if XDEBUG short d_flag = 1; #endif /* DETERMINE WHETHER ANY TRANSLATION IS NECESSARY */ if (!(p->tx_xlat || (p->flowctl & RX))) { c_putc_(p, ch); return (0); } /* SEE IF THIS IS THE DELAY CHARACTER AND DELAY IS IN EFFECT */ if (p->tx_delay && (WORD) ch == p->tx_delaych) { mspause(p->tx_delay); f_tx = FALSE; } /* FLOW CONTROL */ if (!(p->intr & 2)) { while (p->inhold & RXONXOFF) { if (is_key(p->abort_key)) return (USER_CANCELLED); } if (p->flowctl & RRTS_CTS) while (get_cts(p) == LOW) { if (is_key(p->abort_key)) return (USER_CANCELLED); } if (p->flowctl & RDTR_DSR) while (get_dsr(p) == LOW) { if (is_key(p->abort_key)) return (USER_CANCELLED); } } c = ch & 0XFF; /* get the character code for translation */ /* IF ASCII-ONLY FLAG IS TRUE, SEE IF CHARACTER IS ASCII */ if (p->tx_ascii_only) if (!isascii(c)) f_tx = FALSE; /* PERFORM ANY REQUIRED CASE CONVERSION */ if (p->tx_case_convert == UPPER) c = toupper(c); else if (p->tx_case_convert == LOWER) c = tolower(c); /* END-OF-LINE TRANSLATION */ switch (p->tx_eol) { case LF2CR: /* lf->cr */ if (c == LF) c = (p->tx_lastchar == CR) ? LF : CR; break; case CR2LF: /* cr->lf */ if (p->tx_lastchar == CR) { if (c != LF) { p->tx_lastchar = c; if (c != CR) p->tx_f_lastchar = TRUE; c = LF; } else { p->tx_lastchar = c; p->tx_f_lastchar = TRUE; c = CR; } } else if (c == CR) f_tx = FALSE; break; case EOL2SP: /* cr and lf converted to spaces */ if (c == CR || c == LF) { if (c == LF && p->tx_lastchar == CR) f_tx = FALSE; c = SP; } break; case STRIPEOL: /* cr and lf not transmitted */ if (c == CR || c == LF) f_tx = FALSE; break; case LF2CRLF: /* lf -> crlf */ if (c == LF && p->tx_lastchar != LF) { p->tx_lastchar = LF; p->tx_f_lastchar = TRUE; c = CR; } break; case CR2CRLF: /* cr->crlf (prb. w. CRLF) */ if (c == CR) { p->tx_lastchar = LF; p->tx_f_lastchar = TRUE; } break; case CRLF2LF: /* crlf->lf */ if (p->tx_lastchar == CR && c != LF) { p->tx_lastchar = c; p->tx_f_lastchar = TRUE; c = CR; } else if (c == CR) { f_tx = FALSE; p->tx_lastchar = CR; p->tx_f_lastchar = TRUE; } break; case CRLF2CR: /* crlf -> cr */ if (p->tx_lastchar == CR && c == LF) f_tx = FALSE; break; default: break; } /* IF THE TRANSMIT FLAG IS TRUE, SEND THE EXT. CHARACTER TO ALL DEVICES */ if (f_tx) { ch1 = (ch & 0XFF00) | c; /* restore the high byte (scan code) */ /* PERFORM ANY NECESSARY SINGLE CHARACTER TRANSLATION */ if (p->encodec != NULL) ch1 = (*p->encodec)(p, ch1); /* IF ANY ECHOES ARE ON, DO THEM */ if (p->echo & TX) { /* IF LOCAL ECHO IS ON, DISPLAY THE CHARACTER */ if (istxecholocal(p)) (*p->con_out)(p, ch1); /* IF PRINTER ECHO IS ON, PRINT THE CHARACTER */ if (istxechoprn(p)) (*p->p_out)(p, ch1); /* IF THE RECEIVE BUFFER IS ON, BUFFER THE CHARACTER */ if (istxechobuf(p)) (*p->b_out)(p, ch1); } c_putc_(p, ch1); /* THIS IS WHERE WE TRANSMIT IT! */ } /* WAIT FOR REMOTE ECHO */ if (istxechoremote(p)) { if ((c = c_waitc(p, ch1, p->rx_ibdelay)) < 0) { if (c == EOF) return (RX_TIMEOUT); if (c == USER_CANCELLED) return(USER_CANCELLED); } } /* INTERLINE DELAY */ if (p->tx_ildelay && c == (short) p->tx_ildelay_ch) mspause(p->tx_ildelay); /* INTERBYTE DELAY */ else if (p->tx_ibdelay) mspause(p->tx_ibdelay); if (!p->tx_f_lastchar) p->tx_lastchar = ch & 0XFF; else c_flush_tx_(p); return (0); } /* C_PUTS -- Send a nul-terminated string out of the designated port. Return Value: 0 -- success; RX_TIMEOUT -- expected echo from remote not received; USER_CANCELLED -- user cancelled from keyboard; */ short c_puts(COMM_PORT *p, char *s) { short ret = 0; /* p->f_txbusy |= TX_WAIT; */ while (*s != '\0') { ret = c_putc(p, *s++); if (ret) break; } p->f_txbusy &= ~TX_WAIT; if (p->txstart != NULL) (*p->txstart)(p); return (ret); } /* ISTXXLAT -- Determine is TX data translation of any kind is in use. */ short istxxlat(COMM_PORT *p) { if (!p->echo && !p->tx_eol && !p->tx_case_convert && !p->tx_ascii_only && !p->tx_ibdelay && !p->tx_delay && !p->tx_delaych && !p->tx_ildelay && !p->tx_ildelay_ch && !(p->flowctl & TX)) return (FALSE); else return (TRUE); } /* SET_TX_XLAT -- Assign values to data translation parameters. */ short set_tx_xlat(COMM_PORT *p, short item, short value) { return ((*p->set_tx_xlat)(p, item, value)); } /* GET_TX_XLAT -- Return the value of various transmit data translation parameters. */ short get_tx_xlat(COMM_PORT *p, short item) { return ((*p->get_tx_xlat)(p, item)); }