/* Copyright (C) Magna Carta Software, Inc. 1990-1991. All Rights Reserved. Routines to support the Star Gate ACL series of multiport boards. ACL01.C -- This file contains routines that interface the ACL board to the CCT COMM_PORT structure. */ #define CCT_DEVELOPMENT #include #include #include /* ACL_GET -- General purpose parameter retriever for the ACL series of multiport cards. Return values: Success: The value of the UART register that sets stopbits; EOF : Invalid parameter; */ short acl_get(COMM_PORT *p, short cmd) { short ret = 0; char *cba = p->cba; switch (cmd) { /* DATA FORMAT */ case DATABITS: ret = acl_get_databits(cba); break; case PARITY: ret = acl_get_parity(cba); break; case STOPBITS: ret = acl_get_stopbits(cba); break; /* RS-232 */ case CTS: ret = acl_ch_get_modem_status(cba) & 1; break; case DCD: ret = (acl_ch_get_modem_status(cba) & 8) >> 3; break; case DSR: ret = (acl_ch_get_modem_status(cba) & 2) >> 1; break; case DTR: ret = acl_ch_get_modem_ctl(cba) & 1; break; case RI: ret = (acl_ch_get_modem_status(cba) & 4) >> 2; break; case RTS: ret = (acl_ch_get_modem_ctl(cba) & 2) >> 1; break; default: ret = EOF; } return (ret); } /* ACL_GET_SPEED -- Return the current data transfer rate of the channel. */ long acl_get_speed(COMM_PORT *p) { return ((long) acl_ch_get(p->cba, ACL_BAUD_RATE)); } /* ACL_GET_RX_XLAT -- Query the setting of each of the input translation variables used in c_getc(). */ short acl_get_rx_xlat(COMM_PORT *p, short item) { short ret = 0; switch (item) { case XLAT: ret = isrxxlat(p); break; /* OFF or ON */ case LOCAL_ECHO: ret = isrxecholocal(p); break; /* OFF or ON */ case REMOTE_ECHO: ret = isrxechoremote(p); break;/* OFF or ON */ case PRINTER_ECHO: ret = isrxechoprn(p); break; /* OFF or ON */ case CAPTURE_BUFFER_ECHO: ret = isrxechobuf(p); break; /* OFF or ON */ /* EOL is one of: FALSE, LF2CR, CR2LF, EOL2SP, STRIPEOL, LF2CRLF, CR2CRLF, CRLF2LF, CRLF2CR */ case EOL: ret = p->rx_eol; break; case CASE: ret = p->rx_case_convert; break; case ASCII_ONLY: ret = p->rx_ascii_only; break; case INTERBYTE_DELAY: ret = p->rx_ibdelay; break; case FLOWCTL: ret = p->flowctl & RX; break; /* OFF or ON */ case XONCHAR: ret = p->xonchar; break; /* ASCII value */ case XOFFCHAR: ret = p->xoffchar; break; /* ASCII value */ case ABORT_KEY: ret = p->abort_key; break; default: ret = EOF; break; } return (ret); } /* ACL_GET_TX_XLAT -- Return the value of various transmit data translation parameters. */ short acl_get_tx_xlat(COMM_PORT *p, short item) { short ret = 0; switch (item) { case LOCAL_ECHO: ret = istxecholocal(p); break; /* OFF or ON */ case REMOTE_ECHO: ret = istxechoremote(p);break; /* OFF or ON */ case PRINTER_ECHO: ret = istxechoprn(p); break; /* OFF or ON */ case CAPTURE_BUFFER_ECHO: ret = istxechobuf(p); break; /* OFF or ON */ case XLAT: ret = istxxlat(p); break; /* OFF or ON */ /* EOL is one of: FALSE, LF2CR, CR2LF, EOL2SP, STRIPEOL, LF2CRLF, CR2CRLF, CRLF2LF, CRLF2CR */ case EOL: ret = p->tx_eol; break; case CASE: ret = p->tx_case_convert; break; case ASCII_ONLY: ret = p->tx_ascii_only; break; /* INTERBYTE AND INTERLINE DELAYS (in ms.). */ case INTERBYTE_DELAY: ret = p->tx_ibdelay; break; case INTERLINE_DELAY: ret = p->tx_ildelay; break; /* CHARACTER TO TRIGGER INTERLINE DELAY */ case INTERLINE_DELAY_CHAR: ret = p->tx_ildelay_ch; break; case FLOWCTL: ret = acl_ch_get(p->cba, ACL_LINE_PROTOCOL); break; case TX_DELAY: ret = p->tx_delay; break; case TX_DELAYCHAR: ret = p->tx_delaych; break; case XONCHAR: ret = p->xonchar; break; /* ASCII value */ case XOFFCHAR: ret = p->xoffchar; break; /* ASCII value */ /* ASCII CODE OF KEY TO ABORT XOFF */ case ABORT_KEY: ret = p->abort_key; break; default: ret = EOF; break; } return (ret); } /* ACL_INIT_CHANNEL -- Set the parameters for an ACL channel. Note: The Stargate defaults are shown on p.27 of the "ACL Family Technical Reference Manual" (Jan. 1990) as: 9600 8-N-1; No flow ctl; Return Value: 0 -- success; PORT_OPEN -- port already initialized; NO_PORT -- MAX_PORTS already in use; -2 -- ACL board not initialized; */ short acl_init_channel(COMM_PORT *p, ACL *acl, WORD portnum, long speed, WORD databits, WORD parity, WORD stopbits) { short i; if (p->open) return (PORT_OPEN); if (!acl->base_addr) return (-2); /* INITIALIZE DATA IN THE COMM_PORT STRUCTURE */ p->utype = STARGATE_ACL; p->rxdatabits = databits; p->txdatabits = databits; p->parity = parity; p->stopbits = stopbits; p->speed = speed; p->dtr = HIGH; p->rts = HIGH; p->abort_key = ESCAPE; p->cba = acl->cba + acl_ccb_size(acl)*portnum; p->rxbuf = (BYTE FAR_ *) acl->base_addr; p->rxbufend = (BYTE FAR_ *) acl->base_addr + acl_ch_get_ibuf_ea(p->cba); p->rxbufhead = acl->base_addr + acl_ch_get_nctib(p->cba); p->rxbuftail = acl->base_addr + acl_ch_get_ncfib(p->cba); p->txbuf = (BYTE FAR_ *) acl->base_addr; p->txbufend = (BYTE FAR_ *) acl->base_addr + acl_ch_get_obuf_ea(p->cba); p->txbufhead = acl->base_addr + acl_ch_get_nctob(p->cba); p->txbuftail = acl->base_addr + acl_ch_get_ncfob(p->cba); for (i=0; i < 4; i++) p->a_ipr[i] = (void FAR_ *) com_dummy_; /* INITIALIZE DEVICE-SPECIFIC FUNCTION POINTERS */ p->set = acl_set; p->get = acl_get; p->get_rx_xlat = acl_get_rx_xlat; p->set_rx_xlat = acl_set_rx_xlat; p->get_tx_xlat = acl_get_tx_xlat; p->set_tx_xlat = acl_set_tx_xlat; p->set_speed = acl_set_speed; p->get_speed = acl_get_speed; p->rxstat = acl_rxstat; p->txstat = acl_txstat; p->c_read = acl_read; p->c_write = acl_write; #if 0 p->install_ipr = acl_install_ipr; p->deinstall_ipr = acl_deinstall_ipr; p->deinit_port = acl_deinit; p->enable_comm_int = acl_enable_comm_int; p->disable_comm_int = acl_disable_comm_int; #endif /* OPEN THE PORT */ return (c_open_(p)); } /* ACL_READ -- read a byte from a channel of the ACL board. Return: the byte read. */ short acl_read(COMM_PORT *p) { BYTE c; WORD addr; void *cba = p->cba; addr = acl_ch_get_ncfib(cba); c = *(addr++ + p->rxbuf); if (addr > acl_ch_get_ibuf_ea(cba)) acl_ch_set_ncfib(cba, acl_ch_get_ibuf_sa(cba)); else acl_ch_set_ncfib(cba, addr); if (p->rxdatabits == 7) c &= 0X7F; else if (p->rxdatabits == 6) c &= 0X3F; else if (p->rxdatabits == 5) c &= 0X1F; return (c); } /* ACL_RXSTAT -- report whether a character is ready in the channel receive buffer. Return value: FALSE (NULL) if no byte is ready. Else TRUE. */ short acl_rxstat(COMM_PORT *p) { return (acl_ch_get_ncfib(p->cba) != acl_ch_get_nctib(p->cba)); } /* ACL_SET -- General purpose command dispatcher for the ACL board. Return values: 0 -- Success; EOF -- Invalid parameter; */ short acl_set(COMM_PORT *p, short cmd, short value) { short ret = 0; char *cba = p->cba; switch (cmd) { /* DATA FORMAT */ case DATABITS: ret = acl_ch_set_databits(cba, value); break; case PARITY: ret = acl_ch_set_parity(cba, value); break; case STOPBITS: ret = acl_ch_set_stopbits(cba, value); break; case BREAK: ret = acl_ch_get_modem_ctl(cba) | ACL_BREAK; ret = acl_ch_set_modem_ctl(cba, ret); break; /* RS-232 */ case DTR: ret = (acl_ch_get_modem_ctl(cba) & ~ACL_DTR) | value; acl_ch_set_modem_ctl(cba, ret); break; case OUT1: case OUT2: ret = EOF; break; case RTS: value <<= 1; ret = (acl_ch_get_modem_ctl(cba) & ~ACL_RTS) | value; acl_ch_set(cba, ACL_MODEM_CONTROL, ret); break; /* DIAGNOSTIC/OTHER */ case LOOPBACK: ret = acl_set_channel_mode(p, value); break; default: ret = EOF; } return (ret); } /* ACL_SET_CHANNEL_MODE -- Set the mode for an ACL channel. Parameters: ACL *acl -- ptr. to the ACL structure; WORD mode -- desired operating mode; Return Value: the value of the Channel Status Word; */ short acl_set_channel_mode(COMM_PORT *p, WORD mode) { WORD format = (acl_ch_get(p->cba, ACL_DATA_FORMAT) & 0X3F) | mode; return (acl_ch_set_data_format(p->cba, format)); } /* ACL_SET_RX_XLAT -- Specify the type of input translation used by c_getc() and c_gets(). */ short acl_set_rx_xlat(COMM_PORT *p, short item, short value) { WORD format; short ret = 0; switch (item) { case LOCAL_ECHO: case REMOTE_ECHO: case PRINTER_ECHO: case CAPTURE_BUFFER_ECHO: if (value) p->echo |= item; else p->echo &= ~item; break; /* EOL is one of: FALSE, LF2CR, CR2LF, EOL2SP, STRIPEOL, LF2CRLF, CR2CRLF, CRLF2LF, CRLF2CR */ case EOL: p->rx_eol = value; break; case CASE: /* UPPER, LOWER, FALSE */ p->rx_case_convert = value; break; case ASCII_ONLY: p->rx_ascii_only = value; break; case INTERBYTE_DELAY: p->rx_ibdelay = value; break; case TRAILINGBYTE_DELAY: p->rx_tbdelay = value; break; case FLOWCTL: if (value) p->flowctl |= (value >> 4); else p->flowctl &= ~RX; break; case FLOWHIGH: p->flowhigh = value; break; case XONCHAR: /* value to be considered an XON */ format = acl_ch_get(p->cba, ACL_LINE_PROTOCOL); if (value == XON_ALL) acl_ch_set_line_protocol(p->cba, format | ACL_XON_ALL); else { acl_ch_set_line_protocol(p->cba, format & ~ACL_XON_ALL); format = acl_ch_get(p->cba, ACL_IXON_CHARACTERS) & 0X00FF; acl_ch_set_ixon_chars(p->cba, format | (value << 8)); } p->xonchar = value; /* a specific char. */ break; case XOFFCHAR: format = acl_ch_get(p->cba, ACL_IXON_CHARACTERS) & 0XFF00; acl_ch_set_ixon_chars(p->cba, format | value); p->xoffchar = value; break; /* SCAN CODE/CHARACTER CODE OF KEY TO ABORT */ case ABORT_KEY: p->abort_key = value; break; /* INTERRUPT THRESHOLD LEVEL */ case ACL_INPUT_BUFFER_TRIGGER_RATE: ret = acl_ch_set_ibuf_trig(p->cba, value); break; case ACL_INPUT_BUFFER_LWM: ret = acl_ch_set_ibuf_lwm(p->cba, value); break; case ACL_INPUT_BUFFER_HWM: ret = acl_ch_set_ibuf_hwm(p->cba, value); break; default: ret = EOF; break; } if (!ret) { if (value) p->rx_xlat = 1; else p->rx_xlat = isrxxlat(p); } return (ret); } /* ACL_SET_SPEED -- Set the speed of an ACL channel. Parameters: ACL_GCB *acl -- ptr. to the Global Control Block structure; long speed -- desired port speed; Return Value: the value of the Channel Status Word; */ short acl_set_speed(COMM_PORT *p, long speed) { return (acl_ch_set(p->cba, ACL_BAUD_RATE, (WORD) speed)); } /* ACL_SET_TX_XLAT -- Assign values to data translation parameters. */ short acl_set_tx_xlat(COMM_PORT *p, short item, short value) { WORD format; short ret = 0; switch (item) { case LOCAL_ECHO: case REMOTE_ECHO: case PRINTER_ECHO: case CAPTURE_BUFFER_ECHO: if (value) p->echo |= (item << 4); else p->echo &= ~(item << 4); break; /* EOL is one of: FALSE, LF2CR, CR2LF, EOL2SP, STRIPEOL, LF2CRLF, CR2CRLF, CRLF2LF, CRLF2CR */ case EOL: p->tx_eol = value; break; case CASE: /* UPPER, LOWER, NORMAL */ p->tx_case_convert = value; break; case ASCII_ONLY: p->tx_ascii_only = value; break; case INTERBYTE_DELAY: p->tx_ibdelay = value; break; case TX_DELAY: p->tx_delay = value; break; case TX_DELAYCHAR: p->tx_delaych = value; break; case INTERLINE_DELAY: p->tx_ildelay = value; break; case INTERLINE_DELAY_CHAR: p->tx_ildelay_ch = value; break; case FLOWCTL: format = acl_ch_get(p->cba, ACL_LINE_PROTOCOL); if (value) switch (value) { case XONXOFF: acl_ch_set_line_protocol(p->cba, format | ACL_XONXOFF_ASSERT); break; case RTS_CTS: acl_ch_set_line_protocol(p->cba, format | ACL_RTS_CTS_ASSERT); break; default: ret = EOF; break; } else switch (value) { case XONXOFF: acl_ch_set_line_protocol(p->cba, format & ~ACL_XONXOFF_ASSERT); break; case RTS_CTS: acl_ch_set_line_protocol(p->cba, format & ~ACL_RTS_CTS_ASSERT); break; default: ret = EOF; break; } break; case XONCHAR: /* value to be considered an XON */ format = acl_ch_get(p->cba, ACL_IXOFF_CHARACTERS) & 0X00FF; acl_ch_set_ixoff_chars(p->cba, format | (value << 8)); p->xonchar = value; /* a specific char. */ break; case XOFFCHAR: format = acl_ch_get(p->cba, ACL_IXOFF_CHARACTERS) & 0XFF00; acl_ch_set_ixoff_chars(p->cba, format | value); p->xoffchar = value; break; /* ASCII value */ /* SCAN CODE/CHARACTER CODE OF KEY TO ABORT XOFF */ case ABORT_KEY: p->abort_key = value; break; case ACL_OUTPUT_BUFFER_LWM: ret = acl_ch_set_obuf_lwm(p->cba, value); break; default: ret = EOF; break; } if (!ret) { if (value) p->tx_xlat = 1; else p->tx_xlat = istxxlat(p); } return (ret); } /* ACL_TXSTAT -- report whether ACL transmit buffer is ready for a byte. Return: FALSE if transmit buffer is not empty TRUE if transmit buffer is empty. */ short acl_txstat(COMM_PORT *p) { return(acl_ch_get_ncfob(p->cba) != acl_ch_get_nctob(p->cba) + 1); } /* ACL_WRITE -- write a byte to the output buffer of an ACL channel. */ void acl_write(COMM_PORT *p, short c) { char *cba = p->cba; WORD addr = acl_ch_get_nctob(cba); *(p->txbuf + addr++) = (BYTE) c; if (addr > acl_ch_get_obuf_ea(cba)) acl_ch_set_nctob(cba, acl_ch_get_obuf_sa(cba)); else acl_ch_set_nctob(cba, addr); }