|
|
Power 6/32 Unix version 1.2b
#include "../bsc/local.h"
#include "../bsc/bscio.h"
#include "../bsc/bsc.h"
#ifdef BSC_DEBUG
#include "../bsc/bscdebug.h"
long bscdebug = 0;
long bscPC = 0;
#endif
/* D.L.Buck and Associates, Inc. - %H%
*
* COPYRIGHT NOTICE:
* Copyright c %H% - An unpublished work by
* D.L.Buck and Associates, Inc.
*
* PROPRIETARY RIGHTS NOTICE:
* All rights reserved. This document and program contains
* proprietary information of D.L.Buck and Associates,Inc.
* of San Jose, California, U.S.A., embodying confidential
* information, ideas, and expressions, no part of which
* may be reproduced, or transmitted in any form or by any
* means, electronic, mechanical, or otherwise, without
* the written permission of D.L.Buck and Associates, Inc.
*/
/*
* NAME
* bscll - CCI VIOCX' Communications Controller Interface
* and low-level hardware-dependent logic.
* DESCRIPTION
* This file contains the CCI VIOCX' Communications Controller
* Interface routines prepared for the Computer Consoles, Inc.
* Power 5/20 ("Oneida") computer system.
* Included in this module are local initialization and termination
* routines (bsclopn, bsclcls: local open and close),
* local DSR checking logic (bsckdsr),
* local transmit start (bscxmit) and receiver reset (brxres) routines,
* and the interrupt handlers.
* Interrupts are actually fielded by other CCI-written routines, and
* routed to software here.
* These routines are meant to be hardware-dependent.
*/
#ifndef lint
char bscll_id[] = "%W% %Q% CCI";
#endif
#define t_dstat t_col /* Since 4.2 tty struct doesnot have dstat */
/* we use t_col instead. */
/* External variables: */
extern struct bsc bsc[]; /* BSC Device structures: see bsc.c */
extern struct state states[]; /* BSC PSM State table: see bscpsm.c */
extern struct tty vx_tty[];
extern struct vcx vcx[];
char * strlchr();
struct vxcmd * vobtain(); /* Routine to obtain command buffer */
int bscxbsy; /* Tx busy flags */
/*
* Bisync Low-Level Routines.
*
* bsclopn - Local open routine
* bsclcls - Local close routine
* bscparam - Set up BSC device
* bscxmit - Prepare xmit list and start BSC device
* bsctxd - Transmission complete - awaken PSM
* bscrxc - Receive single character
*/
/*
* NAME
* bsclopn -- local line open routine
* SYNOPSIS
* bsclopn (dev,bp)
* dev_t dev;
* struct bsc *bp;
* DESCRIPTION
* Local open routine for CCI's VIOCX'.
* 1. Find VIOCX and associated `vcx' structure.
* 2. Initialize I/O port.
* RETURNS
* 0 for successful open,
* error number for failure (e.g., busy)
*/
/*VARARGS*/
bsclopn(dev, bp)
dev_t dev;
register struct bsc *bp;
{
register struct vcx *xp; /* Ptr to viocx control struct */
struct tty *tp; /* Ptr to associated tty */
extern short vx_use;
register int s;
int port;
dev = minor(dev);
/* 1. Find VIOCX and associated `vcx' structure. */
if ((xp = (struct vcx *) bp->b_devregs) == (struct vcx *)0)
return ENXIO;
#ifdef BSC_DEBUG
bp->b_hlflgs |= BSC_DSR; /* Force DSR on */
#endif
/* 2. Initialize I/O Port. */
port = dev;
/* dev += (xp->v_nbr*16); */
dev = (xp->v_nbr*16) + (dev%NBSC);
tp = &vx_tty[dev]; /* tp -> tty control struct */
tp->t_dev &= 0xf; /* Clear bscport no; upper nible*/
tp->t_dev |= (port << 4); /* Set bscport no */
tp->t_state = TS_ISOPEN; /* Mark as open */
tp->t_line = LDISP; /* MARK LINE SWITCH # */
tp->t_dstat = (char)port; /* save bscport no. */
bscparam(port); /* Go program the device */
/*brxres(port);*/ /* Done in bscparam().dn 2/2/85 */
return 0;
}
/*
* NAME
* bsclcls -- local bsc close
* SYNOPSIS
* bsclcls (dev,bp)
* dev_t dev;
* struct bsc *bp;
* DESCRIPTION
* Local close routine for CCI's VIOCX.
*/
/*ARGSUSED*/
bsclcls (dev,bp)
dev_t dev;
register struct bsc *bp;
{
register struct vcx *xp;
register struct vxcmd *cp;
register struct tty *tp;
int s;
xp = (struct vcx *) bp->b_devregs;
/* s = spl8(); */
cp = vobtain (xp); /* Obtain command buffer */
cp->cmd = MDMCTL; /* Modem control operation */
cp->par[0] = 0; /* Turn DTR off */
cp->par[1] = (dev%NBSC) + xp->v_loport; /* Specify the device */
/* cp->par[1] = dev + xp->v_loport; */ /* Specify the device */
vcmd (xp->v_nbr, &cp->cmd); /* Send the command */
sleep ((caddr_t)cp, BSCPRI); /* Wait for completion */
/*vrelease (xp, cp);*/ /* Done in compl. intr. handler */
bscxbsy &= ~(1<<dev); /* Ensure transmit not busy */
/* splx(s); */
/* tp = &vx_tty[dev+xp->v_nbr*16];*//* Close tty */
tp = &vx_tty[(dev%NBSC)+xp->v_nbr*16];/* Close tty */
tp->t_state = 0; /* Initial state */
tp->t_line = 0; /* Reset line switch */
}
/*
* bscparam -- set up user-controlled BSC device parameters
* if ASCII, set up length=7, odd parity, ASCII SYN
* if EBCDIC, length=8, no parity, EBCDIC SYN
*/
bscparam(dev) /* set up user-controlled BSC device params */
dev_t dev;
{
extern char ebccls[], asccls[];/* character class ptr, tbls */
register struct bsc *bp = &bsc[dev];
register struct vxcmd *cp;
register struct vcx *xp;
register struct tty *tp;
int s;
xp = (struct vcx *) bp->b_devregs;
s = spl8();
cp = vobtain(xp); /* Obtain command buffer */
cp->cmd = LPARAX; /* Load Port Parameters */
cp->par[0] = (bp->b_hlflgs & BSCFDX) ? 1 : 0;
cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port # */
cp->par[2] = 0; /* Not used */
cp->par[3] = 10; /* XMITDTA TimeOut (seconds) */
if (bp->b_hlflgs & BSCASCII) /* ASCII code in use */
{
cp->par[4] = 0x40; /* 7 bits */
cp->par[5] = ASCSYN; /* ASCII SYN char */
cp->par[6] = 0; /* Not used */
cp->par[7] = 1; /* Odd Parity */
bp->b_rxcls = asccls; /* Use ascii char class tbl */
} else { /* EBCDIC code in use */
cp->par[4] = 0xc0; /* 8 bits */
cp->par[5] = EBCSYN; /* EBCDIC SYN char */
cp->par[6] = 0; /* Not used */
cp->par[7] = 0; /* No Parity */
bp->b_rxcls = ebccls; /* Use ebcdic char class tbl */
}
vcmd(xp->v_nbr, &cp->cmd); /* Do LPARAX command */
sleep ((caddr_t)cp, BSCPRI); /* Wait on Completion */
cp = vobtain(xp); /* Obtain command buffer */
cp->cmd = MDMCTL; /* Set Modem Control */
cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port # */
cp->par[0] = MDM_DTR; /* Turn on DTR */
vcmd(xp->v_nbr, &cp->cmd); /* Do MDMCTL command */
sleep ((caddr_t)cp, BSCPRI); /* Wait on Completion */
/*vrelease (xp, cp);*/ /* Done in compl. intr. handler */
splx(s);
brxres(dev); /* Reset receiver */
}
/*
* NAME/SYNOPSIS
* bsckdsr(dev,bp)
* dev_t dev; struct bsc *bp;
* DESCRIPTION
* Check DSR status, post result to b_hlflgs
* ALGORITHM
* Currently ineffective; CCI fixing firmware problem.
*/
/*ARGSUSED*/
bsckdsr(dev,bp) /* Check for current DSR status */
register dev_t dev;
register struct bsc *bp;
{ } /* Completely ineffective */
#define SIZEMASK 0x03ff /* Lower portion of word is transmit length */
#define X_HUNT 0x0200 /* Hunting for synch */
#define X_CNT 0x0003 /* Mask for g/p counter */
/* NAME
* bscxmit - Start transmission on given device
* SYNOPSIS
* bscxmit (dev, newstate)
* dev_t dev;
* int newstate;
* ALGORITHM
* 1. Save 'newstate' as psm state to follow completion of
* transmission. Initialize b_cntl control flags.
* 2. Prepare for transmission. Build VIOCX XMITDTA command
* block, giving pointers and counts for each transmit data
* element. CRC must be calculated before transmission as
* VIOCX' controller emulates simple DMA operation.
* 3. Start transmission by giving XMITDTA command to VIOCX'.
* VALUE RETURNED
* None.
* ERRORS
* None.
*/
bscxmit (dev, newstate)
dev_t dev;
int newstate;
{
register struct bsc *bp = &bsc[dev];
int s, i, j;
struct vxcmd *vobtain();
register struct vcx *xp;
register struct vxcmd *cp;
register char *mp;
char * addr, *phaddr, *p;
caddr_t vtoph();
/* Make sure we don't try to double transmit */
xp = (struct vcx *)bp->b_devregs;
s = spl8();
if (bscxbsy & (1<<dev)) { /* Tx already busy */
splx(s);
return;
}
bscxbsy |= 1<<dev; /* Mark tx busy */
/* 1. Save 'newstate' as psm state to follow completion of
* transmission. Initialize b_cntl control flags.
*/
bp->b_nstate = newstate; /* Next state for PSM when tx done */
/* 2. Prepare for transmission. Build VIOCX XMITDTA command
* block, giving pointers and counts for each transmit data
* element. CRC must be calculated before transmission as
* VIOCX' controller emulates simple DMA operation.
*/
cp = vobtain(xp); /* Obtain XMITDTA Cmd. Buffer */
/* splx(s); */ /* Should be done after vcmd().dn 2/2/85 */
cp->cmd = XMITDTA-1; /* Initially, zero items in tx list */
mp = cp->par; /* First xmit subcommand area */
bp->b_crc[0] = bp->b_crc[1] = 0;/* Reset lrc (we compute) */
for (bp->b_txlptr = &bp->b_txlst[1];/* For each xmit list element,*/
bp->b_txlptr->xptr; /* until end of list, */
++bp->b_txlptr) { /* stepping one list element, */
/* Compute the CRC */
i = bp->b_txlptr->xnum & SIZEMASK; /* Length */
if (!i)
continue; /* zero-length element */
addr = bp->b_txlptr->xptr; /* Address */
addr[i] = '\0';
if (bp->b_txlptr->xnum & X_CRC) /* Needs crc accumulation */
{
register char *next;
if(!(bp->b_hlflgs & BSC_XTRN)){
/* Append CRC after each IUS */
while (next = strlchr(addr,0x1f,
(int)(&bp->b_txlptr->xptr[i]-addr))) {
++next;
crccalc((int)(next-addr),addr,bp);
if (!(bp->b_hlflgs & BSCASCII))
*next++ = bp->b_crc[0];
*next++ = bp->b_crc[1];
bp->b_crc[0] = bp->b_crc[1] = 0;
addr = next;
}
} else {
/* Transparent: skip DLE in DLE-xxx sequence */
while(next = strlchr(addr,0x10,
(int)(&bp->b_txlptr->xptr[i]-addr))) {
++next;
crccalc((int)(next-addr),addr,bp);
addr = ++next;
}
}
/* Compute CRC for last segment */
crccalc((int)(&bp->b_txlptr->xptr[i] - addr), addr, bp);
}
addr = bp->b_txlptr->xptr;
if (i > 254) { /* Max of 254 bytes per VIOC list element */
/* Divide into two transmit segments for DMA */
mp[1] = 254-1; /* Set count */
mp[0] = (dev%NBSC)+xp->v_loport;/* Set device */
phaddr = vtoph(0, addr);
p = (char *)&phaddr;
for (j=0; j < sizeof phaddr; j++)
mp[j+2] = *p++;
i -= 254;
addr += 254;
mp += 6;
++cp->cmd; /* Count # elements*/
}
mp[1] = i-1; /* Set count */
mp[0] = (dev%NBSC)+xp->v_loport; /* Set device */
#if BSC_DEBUG
if (bscdebug & BSCLLX) {
register long ic;
register char *d_addr = addr;
printf("bscxmit: ");
for (ic=0;ic<i;ic++) {
printf("(%lx)",d_addr[ic] & 0xff);
if (!(ic % 15)) printf("\n");
}
}
#endif
phaddr = vtoph(0, addr);
p = (char *)&phaddr;
for (j=0; j < sizeof phaddr; j++)
mp[j+2] = *p++;
mp += 6; /* Advance cmd list element ptr */
++cp->cmd; /* Keep count on # elements */
}
/* 3. Start transmission by giving XMITDTA command to VIOCX'. */
vcmd (xp->v_nbr, &cp->cmd); /* Give XMITDTA cmd. to VIOCX' */
splx(s);
}
/*
* NAME/SYNOPSIS
* bsctxd(dev)
* int dev
* DESCRIPTION
* Called from CCI's interrupt fielder for VIOCX command completion.
* (vxxint, in vcx.c)
* If the command was for a device having tp->t_line == LDISP
* (marked as BSC device in vxreset),
* this routine is called with the port number.
* ALGORITHM
* Turn off Tx Busy flag, set PSM state to previously given newstate
* (see bscxmit), and call PSM.
*/
bsctxd(dev) /* Transmission Done */
int dev;
{
register struct bsc *bp = &bsc[dev];
bscxbsy &= ~(1<<dev); /* Tx done - turn off busy flag */
if (states[bp->b_state].s_type != 's')
return;
bp->b_state = bp->b_nstate; /* New state */
bscpsm((dev_t)dev); /* Restart PSM */
}
/*
* Receive Processing Data and Tables
*/
char adlelst[] = { '0', '1', ';', '<', 0x04 };
char edlelst[] = { 0x70, 0x61, 0x6b, 0x7c, 0x37 };
char dlexxx[] = {C_AK0, C_AK1, C_WAK, C_RVI, C_EOT };
/* Level 0 data classes: */
#define C0_DATA 0 /* Data character */
#define C0_SOH 1 /* Start of Heading */
#define C0_STX 2 /* Start of Text */
#define C0_ETX 3 /* End of Text and Last Block */
#define C0_ETB 4 /* End of Text, not Last Block */
#define C0_IUS 5 /* Unit Separator (2780 only) */
#define C0_SYN 6 /* Synchronous Idle char. */
#define C0_NAK 7 /* Negative Acknowledgement */
#define C0_DLE 8 /* Data Link Escape */
#define C0_ENQ 9 /* Enquiry */
#define C0_EOT 10 /* End of Transmission (Session) */
/* state 0 = initialization
* state 1 = collect heading following SOH
* state 2 = collect data following STX
* state 3 = interpret character after DLE
* state 4 = collect transparent data
* state 5 = interpret character after DLE in transparent mode
*
*
* Date structure of table entries is:
* high order nibble = next state
* low order nibble = action to take
*
*/
/* state:0 1 2 3 4 5 */
char clstbl[] = {
0x02, 0x12, 0x24, 0x0b, 0x44, 0x44, /* 0: data */
0x11, 0x12, 0x24, 0x02, 0x44, 0x44, /* 1: soh */
0x21, 0x20, 0x24, 0x47, 0x44, 0x44, /* 2: stx */
0x02, 0x06, 0x06, 0x02, 0x44, 0x06, /* 3: etx */
0x02, 0x06, 0x06, 0x02, 0x44, 0x06, /* 4: etb */
0x02, 0x12, 0x25, 0x02, 0x44, 0x25, /* 5: ius */
0x0c, 0x1c, 0x2c, 0x0c, 0x44, 0x4c, /* 6: syn */
0x08, 0x12, 0x24, 0x02, 0x44, 0x44, /* 7: nak */
0x30, 0x30, 0x30, 0x02, 0x5c, 0x44, /* 8: dle */
0x09, 0x03, 0x03, 0x02, 0x44, 0x03, /* 9: enq */
0x0a, 0x12, 0x24, 0x0a, 0x44, 0x44}; /*10: eot */
/* SOH, STX, ETX, ETB, IUS, SYN, NAK, DLE, ENQ, EOT */
char ebccls[] = { 0x01,0x02,0x03,0x26,0x1f,0x32,0x3d,0x10,0x2d,0x37 };
char asccls[] = { 0x01,0x02,0x03,0x17,0x1f,0x16,0x15,0x10,0x05,0x04 };
static int tval = 5;
static dev_t sdev;
bel_psm(bp)
register struct bsc *bp;
{
if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r'))
printf("\nthrowing away messages");
else {
bp->b_state = bp->b_rclptr[bp->b_class1];
bp->b_alenb = 0;
bp->b_rclptr = (char *)0;
bscpsm(bp-&bsc[0]);
}
}
bscrxc(c,tp) /* Receive Single Character */
struct tty *tp;
short c;
{
register struct bsc *bp;
register char *p;
register dev_t dev;
int class, stact;
short cc; /* Character in 'c' */
char tc; /* Same char for trace call */
/*** dev = tp - vx_tty;
dev -= (((struct vcx *)(bsc[0].b_devregs))->v_nbr * 16);
***/
dev = (dev_t)tp->t_dstat; /* set in bsclopb() */
bp = &bsc[dev];
cc = c; /* Obtain character */
cc &= 0xff; /* Keep lower 8 bits of char */
tc = (char)cc;
if (bp->b_rxcnt) { /* Do minimal processing - crc/lrc */
crccalc (1, &tc, bp); /* do crc inclusion */
if (--bp->b_rxcnt) /* not end of crc sequence */
goto brxrti;
if (bp->b_class1 == C_IUS) /* IUS - continue */
goto brxrti;
if (bp->b_crc[0] || bp->b_crc[1]) /* if crc error */
bp->b_hlflgs |= BSC_CRCERR;
brx_term: /* Termination of level-0 message */
if ((bp->b_hlflgs & BSC_POLLWT) &&
(bp->b_class1 == C_EOT)) {
bp->b_hlflgs &= ~BSC_POLLWT;
goto brxrti;
}
if (bp->b_class1 == C_EOT) {
bp->b_crc[0] = bp->b_crc[1] = 0;
bp->b_rxhptr = bp->b_iocout.b_hostid;
bp->b_rxhcnt = 0;
bp->b_rxst0 = 0;
}
else brxres(dev);
if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r')) {
/* sdev = dev; */
printf("\nbscrxc: timeout,(r%lx)(s%lx)(t%lx)",
bp->b_rclptr,bp->b_state,states[bp->b_state].s_type&0xff);
timeout(bel_psm,bp,tval);
goto brxrti;
}
bp->b_state = bp->b_rclptr[bp->b_class1];
bp->b_alenb = 0;
bp->b_rclptr = (char *) 0;
if (bp->b_trace)
bsctr (dev, bp->b_class1, 'c');
bscpsm(dev);
goto brxrti;
}
/* Check for HUNT mode */
if (bp->b_cntl & X_HUNT) {
if (cc != 0) /* We get a null when hunt done */
goto brxrti;
/* c = spl8(); */
/* Release command buffer */
/*vrelease (bp->b_devregs, bp->b_cmdbuf);*/
/* splx(c); */
bp->b_cntl &= ~X_HUNT;
goto brxrti;
}
if (bp->b_rclptr == (char *)0) /* Is PSM waiting on us? */
goto brxrti; /* no - ignore this character */
/* Classify current data character, get new state, do action */
p = strlchr(bp->b_rxcls, cc, sizeof asccls);
if (p == (char *) 0)
class = 0;
else class = (p - bp->b_rxcls) + 1;
stact = (clstbl[class*6 + bp->b_rxst0]) & 0xff;
#ifdef BSC_DEBUG
if (bscdebug & LRCVCHAR)
printf("\nbscrcx: (%lx)",cc & 0xff);
if (bscdebug & LSTATE)
printf("\nbscrcx: (lstate=%d)(event=%d)(nstate=%d)(act=%d)",
bp->b_rxst0, class, stact >> 4, stact & 15);
#endif
bp->b_rxst0 = stact >> 4; /* new state 0 */
switch (stact & 15) { /* take action */
case 0:
break;
case 1: /* Prepare to receive data */
bp->b_hlflgs &= ~BSC_XTRN; /* reset transp indicator */
act1a: bp->b_hlflgs &= ~BSC_CRCERR; /* reset CRC error flag */
bp->b_rxdptr = bp->b_buffer; /* receive data ptr */
bp->b_bsize = 0; /* data count <- 0 */
if (class == C0_SOH) { /* if header, reset hptr */
bp->b_rxhptr = bp->b_iocout.b_hostid;
bp->b_rxhcnt = 0;
}
bp->b_crc[0] = bp->b_crc[1] = 0; /* clear crc/lrc */
bp->b_cntl |= X_ACMCRC; /* set accum flag */
break;
case 2: /* Save current character as heading info */
/* Must be 'printable' character in code set in use */
if (bp->b_rxhcnt < sizeof bp->b_iocout.b_hostid &&
(((bp->b_hlflgs & BSCASCII) && cc >= 0x20 && cc < 0x7e) ||
(!(bp->b_hlflgs& BSCASCII) && cc >= 0x40 && cc < 0xf9))) {
*bp->b_rxhptr++ = (char)cc;
++bp->b_rxhcnt;
} else
brxres(dev);
if (bp->b_cntl & X_ACMCRC)
crccalc (1, &tc, bp);
break;
case 3: /* Terminate, class = TTD */
bp->b_class1 = C_TTD;
goto brx_term;
case 5: /* crc/lrc for IUS follows - skip processing it */
bp->b_class1 = C_IUS;
bp->b_rxcnt = (bp->b_hlflgs & BSCASCII) ? 1 : 2;
/* Fall through to case 4, saving IUS as data */
case 4: /* Save current character as data */
crccalc (1, &tc, bp);
if (++bp->b_bsize <= BSCMBLK)
*bp->b_rxdptr++ = (char)cc;
if (bp->b_trace > 1) { /* data trace? */
tc = (char)cc;
bsctr(dev,bp->b_class1,'y',(short)1,&tc);
}
break;
case 6: /* crc/lrc for ETB/ETX follows - skip processing it */
crccalc (1, &tc, bp);
bp->b_class1 = class - C0_ETX + C_ETX;
if (bp->b_hlflgs & BSCASCII)
bp->b_rxcnt = 1; /* Lrc for Ascii */
else
bp->b_rxcnt = 2; /* 2 for crc */
break;
case 7: /* Set crc accum and transparency flag */
bp->b_hlflgs |= BSC_XTRN;
goto act1a;
case 8: /* Terminate; NAK */
bp->b_class1 = C_NAK;
goto brx_term;
case 9: /* Terminate; ENQ */
bp->b_class1 = C_ENQ;
goto brx_term;
case 10:/* Terminate; EOT */
bp->b_class1 = C_EOT;
goto brx_term;
case 11:/* Check for DLE-xxx sequence; terminate with L1 code */
/* if applicable, else ignore */
if (bp->b_hlflgs & BSCASCII) {
p = strlchr(adlelst,cc,sizeof adlelst);
if (p == (char *)0)
break;
bp->b_class1 = dlexxx[p - adlelst];
} else {
p = strlchr(edlelst,cc,sizeof edlelst);
if (p == (char *)0)
break;
bp->b_class1 = dlexxx[p - edlelst];
}
goto brx_term;
case 12:/* Don't accum crc/lrc on this. */
bp->b_alarm = 2*PSMTPS; /* Set 2 sec. timeout */
break;
}
brxrti:;
}
brxres(dev) /* Reset Receiver (Hunt Mode) */
dev_t dev;
{
register struct bsc *bp = &bsc[dev];
register struct vxcmd *cp;
register struct vcx *xp;
struct vxcmd * vobtain();
int x = spl8();
xp = (struct vcx *) bp->b_devregs;
cp = vobtain(xp); /* Get command buffer for Hunt Command */
/* splx(x); */ /* Should be after vcmd(); dn 2/27/85 */
cp->cmd = HUNTMD; /* Synch. Hunt Mode Command */
cp->par[0] = 0; /* Not used */
cp->par[1] = (dev%NBSC)+xp->v_loport; /* Port Number */
vcmd(xp->v_nbr, &cp->cmd); /* Execute Command */
splx(x);
bp->b_cntl |= X_HUNT;
bp->b_crc[0] = bp->b_crc[1] = 0; /* Reset lrc */
bp->b_rxhptr = bp->b_iocout.b_hostid; /* reset ptr for header */
bp->b_rxhcnt = 0; /* Reset current header count */
bp->b_rxst0 = 0; /* Reset lvl 0 state */
}
char * strlchr(s,c,l) /* locate character in string */
register char *s, c;
register int l;
{ while (--l >= 0) {
if (*s == c)
return (s);
++s;
}
return (char *) 0;
}
/* CRC table - crc-16 */
short crctab[] = {
0x0000, /* 00 */
0xc0c1, /* 01 */
0xc181, /* 02 */
0x0140, /* 03 */
0xc301, /* 04 */
0x03c0, /* 05 */
0x0280, /* 06 */
0xc241, /* 07 */
0xc601, /* 08 */
0x06c0, /* 09 */
0x0780, /* 0a */
0xc741, /* 0b */
0x0500, /* 0c */
0xc5c1, /* 0d */
0xc481, /* 0e */
0x0440, /* 0f */
0xcc01, /* 10 */
0x0cc0, /* 11 */
0x0d80, /* 12 */
0xcd41, /* 13 */
0x0f00, /* 14 */
0xcfc1, /* 15 */
0xce81, /* 16 */
0x0e40, /* 17 */
0x0a00, /* 18 */
0xcac1, /* 19 */
0xcb81, /* 1a */
0x0b40, /* 1b */
0xc901, /* 1c */
0x09c0, /* 1d */
0x0880, /* 1e */
0xc841, /* 1f */
0xd801, /* 20 */
0x18c0, /* 21 */
0x1980, /* 22 */
0xd941, /* 23 */
0x1b00, /* 24 */
0xdbc1, /* 25 */
0xda81, /* 26 */
0x1a40, /* 27 */
0x1e00, /* 28 */
0xdec1, /* 29 */
0xdf81, /* 2a */
0x1f40, /* 2b */
0xdd01, /* 2c */
0x1dc0, /* 2d */
0x1c80, /* 2e */
0xdc41, /* 2f */
0x1400, /* 30 */
0xd4c1, /* 31 */
0xd581, /* 32 */
0x1540, /* 33 */
0xd701, /* 34 */
0x17c0, /* 35 */
0x1680, /* 36 */
0xd641, /* 37 */
0xd201, /* 38 */
0x12c0, /* 39 */
0x1380, /* 3a */
0xd341, /* 3b */
0x1100, /* 3c */
0xd1c1, /* 3d */
0xd081, /* 3e */
0x1040, /* 3f */
0xf001, /* 40 */
0x30c0, /* 41 */
0x3180, /* 42 */
0xf141, /* 43 */
0x3300, /* 44 */
0xf3c1, /* 45 */
0xf281, /* 46 */
0x3240, /* 47 */
0x3600, /* 48 */
0xf6c1, /* 49 */
0xf781, /* 4a */
0x3740, /* 4b */
0xf501, /* 4c */
0x35c0, /* 4d */
0x3480, /* 4e */
0xf441, /* 4f */
0x3c00, /* 50 */
0xfcc1, /* 51 */
0xfd81, /* 52 */
0x3d40, /* 53 */
0xff01, /* 54 */
0x3fc0, /* 55 */
0x3e80, /* 56 */
0xfe41, /* 57 */
0xfa01, /* 58 */
0x3ac0, /* 59 */
0x3b80, /* 5a */
0xfb41, /* 5b */
0x3900, /* 5c */
0xf9c1, /* 5d */
0xf881, /* 5e */
0x3840, /* 5f */
0x2800, /* 60 */
0xe8c1, /* 61 */
0xe981, /* 62 */
0x2940, /* 63 */
0xeb01, /* 64 */
0x2bc0, /* 65 */
0x2a80, /* 66 */
0xea41, /* 67 */
0xee01, /* 68 */
0x2ec0, /* 69 */
0x2f80, /* 6a */
0xef41, /* 6b */
0x2d00, /* 6c */
0xedc1, /* 6d */
0xec81, /* 6e */
0x2c40, /* 6f */
0xe401, /* 70 */
0x24c0, /* 71 */
0x2580, /* 72 */
0xe541, /* 73 */
0x2700, /* 74 */
0xe7c1, /* 75 */
0xe681, /* 76 */
0x2640, /* 77 */
0x2200, /* 78 */
0xe2c1, /* 79 */
0xe381, /* 7a */
0x2340, /* 7b */
0xe101, /* 7c */
0x21c0, /* 7d */
0x2080, /* 7e */
0xe041, /* 7f */
0xa001, /* 80 */
0x60c0, /* 81 */
0x6180, /* 82 */
0xa141, /* 83 */
0x6300, /* 84 */
0xa3c1, /* 85 */
0xa281, /* 86 */
0x6240, /* 87 */
0x6600, /* 88 */
0xa6c1, /* 89 */
0xa781, /* 8a */
0x6740, /* 8b */
0xa501, /* 8c */
0x65c0, /* 8d */
0x6480, /* 8e */
0xa441, /* 8f */
0x6c00, /* 90 */
0xacc1, /* 91 */
0xad81, /* 92 */
0x6d40, /* 93 */
0xaf01, /* 94 */
0x6fc0, /* 95 */
0x6e80, /* 96 */
0xae41, /* 97 */
0xaa01, /* 98 */
0x6ac0, /* 99 */
0x6b80, /* 9a */
0xab41, /* 9b */
0x6900, /* 9c */
0xa9c1, /* 9d */
0xa881, /* 9e */
0x6840, /* 9f */
0x7800, /* a0 */
0xb8c1, /* a1 */
0xb981, /* a2 */
0x7940, /* a3 */
0xbb01, /* a4 */
0x7bc0, /* a5 */
0x7a80, /* a6 */
0xba41, /* a7 */
0xbe01, /* a8 */
0x7ec0, /* a9 */
0x7f80, /* aa */
0xbf41, /* ab */
0x7d00, /* ac */
0xbdc1, /* ad */
0xbc81, /* ae */
0x7c40, /* af */
0xb401, /* b0 */
0x74c0, /* b1 */
0x7580, /* b2 */
0xb541, /* b3 */
0x7700, /* b4 */
0xb7c1, /* b5 */
0xb681, /* b6 */
0x7640, /* b7 */
0x7200, /* b8 */
0xb2c1, /* b9 */
0xb381, /* ba */
0x7340, /* bb */
0xb101, /* bc */
0x71c0, /* bd */
0x7080, /* be */
0xb041, /* bf */
0x5000, /* c0 */
0x90c1, /* c1 */
0x9181, /* c2 */
0x5140, /* c3 */
0x9301, /* c4 */
0x53c0, /* c5 */
0x5280, /* c6 */
0x9241, /* c7 */
0x9601, /* c8 */
0x56c0, /* c9 */
0x5780, /* ca */
0x9741, /* cb */
0x5500, /* cc */
0x95c1, /* cd */
0x9481, /* ce */
0x5440, /* cf */
0x9c01, /* d0 */
0x5cc0, /* d1 */
0x5d80, /* d2 */
0x9d41, /* d3 */
0x5f00, /* d4 */
0x9fc1, /* d5 */
0x9e81, /* d6 */
0x5e40, /* d7 */
0x5a00, /* d8 */
0x9ac1, /* d9 */
0x9b81, /* da */
0x5b40, /* db */
0x9901, /* dc */
0x59c0, /* dd */
0x5880, /* de */
0x9841, /* df */
0x8801, /* e0 */
0x48c0, /* e1 */
0x4980, /* e2 */
0x8941, /* e3 */
0x4b00, /* e4 */
0x8bc1, /* e5 */
0x8a81, /* e6 */
0x4a40, /* e7 */
0x4e00, /* e8 */
0x8ec1, /* e9 */
0x8f81, /* ea */
0x4f40, /* eb */
0x8d01, /* ec */
0x4dc0, /* ed */
0x4c80, /* ee */
0x8c41, /* ef */
0x4400, /* f0 */
0x84c1, /* f1 */
0x8581, /* f2 */
0x4540, /* f3 */
0x8701, /* f4 */
0x47c0, /* f5 */
0x4680, /* f6 */
0x8641, /* f7 */
0x8201, /* f8 */
0x42c0, /* f9 */
0x4380, /* fa */
0x8341, /* fb */
0x4100, /* fc */
0x81c1, /* fd */
0x8081, /* fe */
0x4040, /* ff */
};
crccalc(count, buffer, bp)
register int count;
register char *buffer;
struct bsc *bp;
{
register unsigned int work, crc;
crc = ((bp->b_crc[1] & 0xff)<<8) | (bp->b_crc[0] & 0xff);
if (bp->b_hlflgs & BSCASCII)
while (--count >= 0) {
work = (*buffer++) & 0xff;
crc ^= work | (work << 8);
}
else
while (--count >= 0) {
work = crctab[0xff & (crc ^ *buffer++)];
crc = (work & 0xff00) |
(0xff & ((crc >> 8) ^ work));
}
bp->b_crc[0] = crc;
bp->b_crc[1] = crc >> 8;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.