Annotation of cci/sys/bsc/bscll.c, revision 1.1

1.1     ! root        1: #include "../bsc/local.h"
        !             2: #include "../bsc/bscio.h"
        !             3: #include "../bsc/bsc.h"
        !             4: 
        !             5: #ifdef BSC_DEBUG
        !             6: #include "../bsc/bscdebug.h"
        !             7: long bscdebug = 0;
        !             8: long bscPC = 0;
        !             9: #endif
        !            10: 
        !            11: /*     D.L.Buck and Associates, Inc. - %H%
        !            12:  *
        !            13:  *     COPYRIGHT NOTICE:
        !            14:  *             Copyright c %H% - An unpublished work by 
        !            15:  *             D.L.Buck and Associates, Inc.
        !            16:  *
        !            17:  *     PROPRIETARY RIGHTS NOTICE:
        !            18:  *             All rights reserved. This document and program contains
        !            19:  *             proprietary information of D.L.Buck and Associates,Inc.
        !            20:  *             of San Jose, California, U.S.A., embodying confidential
        !            21:  *             information,  ideas, and expressions,  no part of which
        !            22:  *             may be reproduced, or transmitted in any form or by any
        !            23:  *             means,  electronic,  mechanical,  or otherwise, without
        !            24:  *             the written permission of D.L.Buck and Associates, Inc.
        !            25:  */
        !            26: 
        !            27: /*
        !            28:  * NAME
        !            29:  *     bscll - CCI VIOCX' Communications Controller Interface
        !            30:  *     and low-level hardware-dependent logic.
        !            31:  * DESCRIPTION
        !            32:  *     This file contains the CCI VIOCX' Communications Controller
        !            33:  *     Interface routines prepared for the Computer Consoles, Inc.
        !            34:  *     Power 5/20 ("Oneida") computer system.
        !            35:  *     Included in this module are local initialization and termination
        !            36:  *     routines (bsclopn, bsclcls: local open and close),
        !            37:  *     local DSR checking logic (bsckdsr),
        !            38:  *     local transmit start (bscxmit) and receiver reset (brxres) routines,
        !            39:  *     and the interrupt handlers.
        !            40:  *     Interrupts are actually fielded by other CCI-written routines, and
        !            41:  *     routed to software here.
        !            42:  *     These routines are meant to be hardware-dependent.
        !            43:  */
        !            44: 
        !            45: #ifndef lint
        !            46: char bscll_id[] = "%W% %Q% CCI";
        !            47: #endif
        !            48: 
        !            49: #define t_dstat        t_col           /* Since 4.2 tty struct doesnot have dstat */
        !            50:                                /* we use t_col instead.                */
        !            51: 
        !            52: /* External variables:                                                 */
        !            53: extern struct bsc bsc[];       /* BSC Device structures: see bsc.c     */
        !            54: extern struct state states[];  /* BSC PSM State table: see bscpsm.c    */
        !            55: extern struct tty vx_tty[];
        !            56: extern struct vcx vcx[];
        !            57: char * strlchr();
        !            58: struct vxcmd * vobtain();      /* Routine to obtain command buffer     */
        !            59: int bscxbsy;                   /* Tx busy flags                        */
        !            60: 
        !            61: /*
        !            62:  *     Bisync Low-Level Routines.
        !            63:  *
        !            64:  *     bsclopn - Local open routine
        !            65:  *     bsclcls - Local close routine
        !            66:  *     bscparam - Set up BSC device
        !            67:  *     bscxmit - Prepare xmit list and start BSC device
        !            68:  *     bsctxd  - Transmission complete - awaken PSM
        !            69:  *     bscrxc  - Receive single character
        !            70:  */
        !            71: 
        !            72: /*
        !            73:  * NAME
        !            74:  *     bsclopn -- local line open routine
        !            75:  * SYNOPSIS
        !            76:  *     bsclopn (dev,bp)
        !            77:  *     dev_t dev;
        !            78:  *     struct bsc *bp;
        !            79:  * DESCRIPTION
        !            80:  *     Local open routine for CCI's VIOCX'.
        !            81:  *     1. Find VIOCX and associated `vcx' structure.
        !            82:  *     2. Initialize I/O port.
        !            83:  * RETURNS
        !            84:  *     0 for successful open,
        !            85:  *     error number for failure (e.g., busy)
        !            86:  */
        !            87: /*VARARGS*/
        !            88: bsclopn(dev, bp)
        !            89: dev_t dev;
        !            90: register struct bsc *bp;
        !            91: {
        !            92:        register struct vcx *xp;        /* Ptr to viocx control struct  */
        !            93:        struct tty *tp;                 /* Ptr to associated tty        */
        !            94:        extern short vx_use;
        !            95:        register int s;
        !            96:        int port;
        !            97: 
        !            98:        dev = minor(dev);
        !            99:        /* 1. Find VIOCX and associated `vcx' structure.                */
        !           100:        if ((xp = (struct vcx *) bp->b_devregs) == (struct vcx *)0)
        !           101:                return ENXIO;
        !           102: #ifdef BSC_DEBUG 
        !           103:         bp->b_hlflgs |= BSC_DSR;       /* Force DSR on                 */
        !           104: #endif
        !           105: 
        !           106:        /* 2. Initialize I/O Port.                                      */
        !           107:        port = dev;
        !           108: /*     dev += (xp->v_nbr*16);   */
        !           109:        dev  = (xp->v_nbr*16) + (dev%NBSC);   
        !           110:        tp = &vx_tty[dev];              /* tp -> tty control struct     */
        !           111:        tp->t_dev &= 0xf;               /* Clear bscport no; upper nible*/
        !           112:        tp->t_dev |= (port << 4);       /* Set bscport no               */
        !           113:        tp->t_state = TS_ISOPEN;        /* Mark as open                 */
        !           114:        tp->t_line = LDISP;             /* MARK LINE SWITCH #           */
        !           115:         tp->t_dstat = (char)port;       /* save bscport no. */
        !           116:        bscparam(port);                 /* Go program the device        */
        !           117:        /*brxres(port);*/               /* Done in bscparam().dn 2/2/85 */
        !           118:        return 0;
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * NAME
        !           123:  *     bsclcls -- local bsc close
        !           124:  * SYNOPSIS
        !           125:  *     bsclcls (dev,bp)
        !           126:  *     dev_t dev;
        !           127:  *     struct bsc *bp;
        !           128:  * DESCRIPTION
        !           129:  *     Local close routine for CCI's VIOCX.
        !           130:  */
        !           131: /*ARGSUSED*/
        !           132: bsclcls (dev,bp)
        !           133: dev_t dev;
        !           134: register struct bsc *bp;
        !           135: {
        !           136:        register struct vcx *xp;
        !           137:        register struct vxcmd *cp;
        !           138:        register struct tty *tp;
        !           139:        int s;
        !           140: 
        !           141:        xp = (struct vcx *) bp->b_devregs;
        !           142: /*     s = spl8();     */           
        !           143:        cp = vobtain (xp);              /* Obtain command buffer        */
        !           144:        cp->cmd = MDMCTL;               /* Modem control operation      */
        !           145:        cp->par[0] = 0;                 /* Turn DTR off                 */
        !           146:        cp->par[1] = (dev%NBSC) + xp->v_loport; /* Specify the device   */
        !           147: /*     cp->par[1] = dev + xp->v_loport;  */    /* Specify the device   */
        !           148:        vcmd (xp->v_nbr, &cp->cmd);     /* Send the command             */
        !           149:        sleep ((caddr_t)cp, BSCPRI);    /* Wait for completion          */
        !           150:        /*vrelease (xp, cp);*/          /* Done in compl. intr. handler */
        !           151:        bscxbsy &= ~(1<<dev);           /* Ensure transmit not busy     */
        !           152: /*     splx(s);    */
        !           153: 
        !           154: /*     tp = &vx_tty[dev+xp->v_nbr*16];*//* Close tty                   */
        !           155:        tp = &vx_tty[(dev%NBSC)+xp->v_nbr*16];/* Close tty              */
        !           156:        tp->t_state = 0;                /* Initial state                */
        !           157:        tp->t_line = 0;                 /* Reset line switch            */
        !           158: }
        !           159: 
        !           160: /*
        !           161:  *     bscparam -- set up user-controlled BSC device parameters
        !           162:  *             if ASCII, set up length=7, odd parity, ASCII SYN
        !           163:  *             if EBCDIC,       length=8, no parity, EBCDIC SYN
        !           164:  */
        !           165: bscparam(dev)                  /* set up user-controlled BSC device params */
        !           166: dev_t dev;
        !           167: {
        !           168:        extern char ebccls[], asccls[];/* character class ptr, tbls     */
        !           169:        register struct bsc *bp = &bsc[dev];
        !           170:        register struct vxcmd *cp;
        !           171:        register struct vcx *xp;
        !           172:        register struct tty *tp;
        !           173:        int s;
        !           174: 
        !           175:        xp = (struct vcx *) bp->b_devregs;
        !           176:        s = spl8();
        !           177:        cp = vobtain(xp);               /* Obtain command buffer        */
        !           178:        cp->cmd = LPARAX;               /* Load Port Parameters         */
        !           179:        cp->par[0] = (bp->b_hlflgs & BSCFDX) ? 1 : 0;
        !           180:        cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port #               */
        !           181:        cp->par[2] = 0;                 /* Not used                     */
        !           182:        cp->par[3] = 10;                /* XMITDTA TimeOut (seconds)    */
        !           183:        if (bp->b_hlflgs & BSCASCII)    /* ASCII code in use            */
        !           184:        {
        !           185:                cp->par[4] = 0x40;      /* 7 bits                       */
        !           186:                cp->par[5] = ASCSYN;    /* ASCII SYN char               */
        !           187:                cp->par[6] = 0;         /* Not used                     */
        !           188:                cp->par[7] = 1;         /* Odd Parity                   */
        !           189:                bp->b_rxcls = asccls;   /* Use ascii char class tbl     */
        !           190:        } else {                /* EBCDIC code in use                   */
        !           191:                cp->par[4] = 0xc0;      /* 8 bits                       */
        !           192:                cp->par[5] = EBCSYN;    /* EBCDIC SYN char              */
        !           193:                cp->par[6] = 0;         /* Not used                     */
        !           194:                cp->par[7] = 0;         /* No Parity                    */
        !           195:                bp->b_rxcls = ebccls;   /* Use ebcdic char class tbl    */
        !           196:        }
        !           197:        vcmd(xp->v_nbr, &cp->cmd);      /* Do LPARAX command            */
        !           198:        sleep ((caddr_t)cp, BSCPRI);    /* Wait on Completion           */
        !           199: 
        !           200:        cp = vobtain(xp);               /* Obtain command buffer        */
        !           201:        cp->cmd = MDMCTL;               /* Set Modem Control            */
        !           202:        cp->par[1] = (dev%NBSC) + xp->v_loport; /* Port #               */
        !           203:        cp->par[0] = MDM_DTR;           /* Turn on DTR                  */
        !           204:        vcmd(xp->v_nbr, &cp->cmd);      /* Do MDMCTL command            */
        !           205:        sleep ((caddr_t)cp, BSCPRI);    /* Wait on Completion           */
        !           206: 
        !           207:        /*vrelease (xp, cp);*/          /* Done in compl. intr. handler */
        !           208:        splx(s);
        !           209:        brxres(dev);                    /* Reset receiver               */
        !           210: }
        !           211: 
        !           212: /*
        !           213:  * NAME/SYNOPSIS
        !           214:  *     bsckdsr(dev,bp)
        !           215:  *     dev_t dev; struct bsc *bp;
        !           216:  * DESCRIPTION
        !           217:  *     Check DSR status, post result to b_hlflgs
        !           218:  * ALGORITHM
        !           219:  *     Currently ineffective; CCI fixing firmware problem.
        !           220:  */
        !           221: /*ARGSUSED*/
        !           222: bsckdsr(dev,bp)                /* Check for current DSR status                 */
        !           223: register dev_t dev;
        !           224: register struct bsc *bp;
        !           225: {      }       /* Completely ineffective */
        !           226: 
        !           227: #define        SIZEMASK 0x03ff /* Lower portion of word is transmit length     */
        !           228: #define X_HUNT 0x0200  /* Hunting for synch                            */
        !           229: #define        X_CNT   0x0003  /* Mask for g/p counter                         */
        !           230: 
        !           231: /*     NAME
        !           232:  *             bscxmit - Start transmission on given device
        !           233:  *     SYNOPSIS
        !           234:  *             bscxmit (dev, newstate)
        !           235:  *             dev_t dev;
        !           236:  *             int newstate;
        !           237:  *     ALGORITHM
        !           238:  *             1. Save 'newstate' as psm state to follow completion of
        !           239:  *                transmission.  Initialize b_cntl control flags.
        !           240:  *             2. Prepare for transmission.  Build VIOCX XMITDTA command
        !           241:  *                block, giving pointers and counts for each transmit data
        !           242:  *                element.  CRC must be calculated before transmission as
        !           243:  *                VIOCX' controller emulates simple DMA operation.
        !           244:  *             3. Start transmission by giving XMITDTA command to VIOCX'.
        !           245:  *     VALUE RETURNED
        !           246:  *             None.
        !           247:  *     ERRORS
        !           248:  *             None.
        !           249:  */
        !           250: bscxmit (dev, newstate)
        !           251: dev_t dev;
        !           252: int newstate;
        !           253: {
        !           254:        register struct bsc *bp = &bsc[dev];
        !           255:        int s, i, j;
        !           256:        struct vxcmd *vobtain();
        !           257:        register struct vcx *xp;
        !           258:        register struct vxcmd *cp;
        !           259:        register char *mp;
        !           260:        char * addr, *phaddr, *p;
        !           261:        caddr_t vtoph();
        !           262: 
        !           263:        /* Make sure we don't try to double transmit                    */
        !           264:        xp = (struct vcx *)bp->b_devregs;
        !           265:        s = spl8();
        !           266:        if (bscxbsy & (1<<dev)) {       /* Tx already busy              */
        !           267:                splx(s);
        !           268:                return;
        !           269:        }
        !           270:        bscxbsy |= 1<<dev;              /* Mark tx busy                 */
        !           271:        /* 1. Save 'newstate' as psm state to follow completion of
        !           272:         *    transmission.  Initialize b_cntl control flags.
        !           273:         */
        !           274:        bp->b_nstate = newstate;        /* Next state for PSM when tx done */
        !           275: 
        !           276:        /* 2. Prepare for transmission.  Build VIOCX XMITDTA command
        !           277:         *    block, giving pointers and counts for each transmit data
        !           278:         *    element.  CRC must be calculated before transmission as
        !           279:         *    VIOCX' controller emulates simple DMA operation.
        !           280:         */
        !           281:        cp = vobtain(xp);               /* Obtain XMITDTA Cmd. Buffer   */
        !           282: /*     splx(s);   */           /* Should be done after vcmd().dn 2/2/85 */
        !           283:        cp->cmd = XMITDTA-1;            /* Initially, zero items in tx list */
        !           284:        mp = cp->par;   /* First xmit subcommand area   */
        !           285:        bp->b_crc[0] = bp->b_crc[1] = 0;/* Reset lrc (we compute)       */
        !           286: 
        !           287:        for (bp->b_txlptr = &bp->b_txlst[1];/* For each xmit list element,*/
        !           288:             bp->b_txlptr->xptr;        /* until end of list,           */
        !           289:             ++bp->b_txlptr) {          /* stepping one list element,   */
        !           290:                /*                         Compute the CRC              */
        !           291:                i = bp->b_txlptr->xnum & SIZEMASK;      /* Length       */
        !           292:                if (!i)
        !           293:                        continue;       /* zero-length element          */
        !           294:                addr = bp->b_txlptr->xptr;              /* Address      */
        !           295:                addr[i] = '\0';
        !           296:                if (bp->b_txlptr->xnum & X_CRC) /* Needs crc accumulation */
        !           297:                {       
        !           298:                        register char *next;
        !           299:                        if(!(bp->b_hlflgs & BSC_XTRN)){
        !           300:                        /* Append CRC after each IUS                    */
        !           301:                            while (next = strlchr(addr,0x1f,
        !           302:                               (int)(&bp->b_txlptr->xptr[i]-addr))) {
        !           303:                                   ++next;
        !           304:                                   crccalc((int)(next-addr),addr,bp);
        !           305:                                   if (!(bp->b_hlflgs & BSCASCII))
        !           306:                                        *next++ = bp->b_crc[0];
        !           307:                                   *next++ = bp->b_crc[1];
        !           308:                                   bp->b_crc[0] = bp->b_crc[1] = 0;
        !           309:                                   addr = next;
        !           310:                           }
        !           311:                        } else {
        !           312:                        /* Transparent: skip DLE in DLE-xxx sequence    */
        !           313:                            while(next = strlchr(addr,0x10,
        !           314:                                (int)(&bp->b_txlptr->xptr[i]-addr))) {
        !           315:                                    ++next;
        !           316:                                    crccalc((int)(next-addr),addr,bp);
        !           317:                                    addr = ++next;
        !           318:                            }
        !           319:                        }
        !           320:                        /* Compute CRC for last segment                 */
        !           321:                        crccalc((int)(&bp->b_txlptr->xptr[i] - addr), addr, bp);
        !           322:                }
        !           323:                addr = bp->b_txlptr->xptr;
        !           324:                if (i > 254) {  /* Max of 254 bytes per VIOC list element */
        !           325:                        /* Divide into two transmit segments for DMA    */
        !           326:                        mp[1] = 254-1;  /* Set count            */
        !           327:                        mp[0] = (dev%NBSC)+xp->v_loport;/* Set device   */
        !           328:                        phaddr = vtoph(0, addr);
        !           329:                        p = (char *)&phaddr;
        !           330:                        for (j=0; j < sizeof phaddr; j++)
        !           331:                                mp[j+2] = *p++;
        !           332:                        i -= 254;
        !           333:                        addr += 254;
        !           334:                        mp += 6;
        !           335:                        ++cp->cmd;                      /* Count # elements*/
        !           336:                }
        !           337:                mp[1] = i-1;                            /* Set count    */
        !           338:                mp[0] = (dev%NBSC)+xp->v_loport;        /* Set device   */
        !           339: #if BSC_DEBUG
        !           340:                if (bscdebug & BSCLLX) {
        !           341:                        register long ic;
        !           342:                        register char *d_addr = addr;
        !           343: 
        !           344:                        printf("bscxmit: ");
        !           345:                        for (ic=0;ic<i;ic++) {
        !           346:                                printf("(%lx)",d_addr[ic] & 0xff);
        !           347:                                if (!(ic % 15)) printf("\n");
        !           348:                        }
        !           349:                }
        !           350: #endif
        !           351:                phaddr = vtoph(0, addr);
        !           352:                p = (char *)&phaddr;
        !           353:                for (j=0; j < sizeof phaddr; j++)
        !           354:                        mp[j+2] = *p++;
        !           355:                mp += 6;                /* Advance cmd list element ptr */
        !           356:                ++cp->cmd;              /* Keep count on # elements     */
        !           357:        }
        !           358: 
        !           359:        /* 3. Start transmission by giving XMITDTA command to VIOCX'.   */
        !           360:        vcmd (xp->v_nbr, &cp->cmd);     /* Give XMITDTA cmd. to VIOCX'  */
        !           361:         splx(s);
        !           362: }
        !           363: 
        !           364: /*
        !           365:  * NAME/SYNOPSIS
        !           366:  *     bsctxd(dev)
        !           367:  *     int dev
        !           368:  * DESCRIPTION
        !           369:  *     Called from CCI's interrupt fielder for VIOCX command completion.
        !           370:  *     (vxxint, in vcx.c)
        !           371:  *     If the command was for a device having tp->t_line == LDISP
        !           372:  *     (marked as BSC device in vxreset),
        !           373:  *     this routine is called with the port number.
        !           374:  * ALGORITHM
        !           375:  *     Turn off Tx Busy flag, set PSM state to previously given newstate
        !           376:  *     (see bscxmit), and call PSM.
        !           377:  */
        !           378: bsctxd(dev)                    /* Transmission Done */
        !           379: int dev;
        !           380: {
        !           381:        register struct bsc *bp = &bsc[dev];
        !           382: 
        !           383:        bscxbsy &= ~(1<<dev);           /* Tx done - turn off busy flag */
        !           384:        if (states[bp->b_state].s_type != 's')
        !           385:                return;
        !           386:        bp->b_state = bp->b_nstate;     /* New state                    */
        !           387:        bscpsm((dev_t)dev);             /* Restart PSM                  */
        !           388: }
        !           389: 
        !           390: /*
        !           391:  * Receive Processing Data and Tables
        !           392:  */
        !           393: char adlelst[] = { '0', '1', ';', '<', 0x04 };
        !           394: char edlelst[] = { 0x70, 0x61, 0x6b, 0x7c, 0x37 };
        !           395: char dlexxx[] =  {C_AK0, C_AK1, C_WAK, C_RVI, C_EOT };
        !           396: 
        !           397: /* Level 0 data classes: */
        !           398: #define        C0_DATA 0       /* Data character                               */
        !           399: #define        C0_SOH  1       /* Start of Heading                             */
        !           400: #define        C0_STX  2       /* Start of Text                                */
        !           401: #define        C0_ETX  3       /* End of Text and Last Block                   */
        !           402: #define        C0_ETB  4       /* End of Text, not Last Block                  */
        !           403: #define        C0_IUS  5       /* Unit Separator (2780 only)                   */
        !           404: #define        C0_SYN  6       /* Synchronous Idle char.                       */
        !           405: #define        C0_NAK  7       /* Negative Acknowledgement                     */
        !           406: #define        C0_DLE  8       /* Data Link Escape                             */
        !           407: #define        C0_ENQ  9       /* Enquiry                                      */
        !           408: #define        C0_EOT  10      /* End of Transmission (Session)                */
        !           409: 
        !           410: /* state 0 = initialization
        !           411:  * state 1 = collect heading following SOH
        !           412:  * state 2 = collect data following STX
        !           413:  * state 3 = interpret character after DLE
        !           414:  * state 4 = collect transparent data
        !           415:  * state 5 = interpret character after DLE in transparent mode
        !           416:  *
        !           417:  *
        !           418:  * Date structure of table entries is:
        !           419:  *     high order nibble = next state
        !           420:  *     low order nibble  = action to take
        !           421:  *
        !           422:  */
        !           423: 
        !           424:        /* state:0     1     2     3     4     5 */
        !           425: char clstbl[] = {
        !           426:                0x02, 0x12, 0x24, 0x0b, 0x44, 0x44,     /* 0: data      */
        !           427:                0x11, 0x12, 0x24, 0x02, 0x44, 0x44,     /* 1: soh       */
        !           428:                0x21, 0x20, 0x24, 0x47, 0x44, 0x44,     /* 2: stx       */
        !           429:                0x02, 0x06, 0x06, 0x02, 0x44, 0x06,     /* 3: etx       */
        !           430:                0x02, 0x06, 0x06, 0x02, 0x44, 0x06,     /* 4: etb       */
        !           431:                0x02, 0x12, 0x25, 0x02, 0x44, 0x25,     /* 5: ius       */
        !           432:                0x0c, 0x1c, 0x2c, 0x0c, 0x44, 0x4c,     /* 6: syn       */
        !           433:                0x08, 0x12, 0x24, 0x02, 0x44, 0x44,     /* 7: nak       */
        !           434:                0x30, 0x30, 0x30, 0x02, 0x5c, 0x44,     /* 8: dle       */
        !           435:                0x09, 0x03, 0x03, 0x02, 0x44, 0x03,     /* 9: enq       */
        !           436:                0x0a, 0x12, 0x24, 0x0a, 0x44, 0x44};    /*10: eot       */
        !           437: 
        !           438:        /*         SOH, STX, ETX, ETB, IUS, SYN, NAK, DLE, ENQ, EOT */
        !           439: char ebccls[] = { 0x01,0x02,0x03,0x26,0x1f,0x32,0x3d,0x10,0x2d,0x37 };
        !           440: char asccls[] = { 0x01,0x02,0x03,0x17,0x1f,0x16,0x15,0x10,0x05,0x04 };
        !           441: 
        !           442: static int tval = 5;
        !           443: static dev_t sdev;
        !           444: 
        !           445: bel_psm(bp)
        !           446: register struct bsc *bp;
        !           447: {
        !           448:        if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r'))
        !           449:                printf("\nthrowing away messages");
        !           450:        else {
        !           451:                bp->b_state = bp->b_rclptr[bp->b_class1];
        !           452:                bp->b_alenb = 0;
        !           453:                bp->b_rclptr = (char *)0;
        !           454:                bscpsm(bp-&bsc[0]);
        !           455:        }
        !           456: }
        !           457: 
        !           458: bscrxc(c,tp)                   /* Receive Single Character */
        !           459: struct tty *tp;
        !           460: short c;
        !           461: {
        !           462:        register struct bsc *bp;
        !           463:        register char *p;
        !           464:        register dev_t dev;
        !           465:        int class, stact;
        !           466:        short cc;                       /* Character in 'c'             */
        !           467:        char tc;                        /* Same char for trace call     */
        !           468: 
        !           469: /***   dev = tp - vx_tty;
        !           470:        dev -= (((struct vcx *)(bsc[0].b_devregs))->v_nbr * 16);
        !           471: ***/
        !           472:         dev = (dev_t)tp->t_dstat;      /* set in bsclopb() */
        !           473:        bp = &bsc[dev];
        !           474:        cc = c;                         /* Obtain character             */
        !           475:        cc &= 0xff;                     /* Keep lower 8 bits of char    */
        !           476:        tc = (char)cc;
        !           477:        if (bp->b_rxcnt) {              /* Do minimal processing - crc/lrc */
        !           478:                crccalc (1, &tc, bp);   /* do crc inclusion */
        !           479:                if (--bp->b_rxcnt)      /* not end of crc sequence */
        !           480:                        goto brxrti;
        !           481:                if (bp->b_class1 == C_IUS)      /* IUS - continue */
        !           482:                        goto brxrti;
        !           483:                if (bp->b_crc[0] || bp->b_crc[1])       /* if crc error */
        !           484:                        bp->b_hlflgs |= BSC_CRCERR;
        !           485: brx_term:      /* Termination of level-0 message */
        !           486:                if ((bp->b_hlflgs & BSC_POLLWT) && 
        !           487:                        (bp->b_class1 == C_EOT)) {
        !           488:                        bp->b_hlflgs &= ~BSC_POLLWT;
        !           489:                        goto brxrti;
        !           490:                }
        !           491:                if (bp->b_class1 == C_EOT) {
        !           492:                        bp->b_crc[0] = bp->b_crc[1] = 0;
        !           493:                        bp->b_rxhptr = bp->b_iocout.b_hostid;
        !           494:                        bp->b_rxhcnt = 0;
        !           495:                        bp->b_rxst0 = 0;
        !           496:                }
        !           497:                else brxres(dev);
        !           498:                if ((!bp->b_rclptr) || (states[bp->b_state].s_type != 'r')) {
        !           499:                /*      sdev = dev;     */
        !           500: printf("\nbscrxc: timeout,(r%lx)(s%lx)(t%lx)",
        !           501:        bp->b_rclptr,bp->b_state,states[bp->b_state].s_type&0xff);
        !           502:                        timeout(bel_psm,bp,tval);
        !           503:                        goto brxrti;
        !           504:                }
        !           505:                bp->b_state = bp->b_rclptr[bp->b_class1];
        !           506:                bp->b_alenb = 0;
        !           507:                bp->b_rclptr = (char *) 0;
        !           508:                if (bp->b_trace)
        !           509:                        bsctr (dev, bp->b_class1, 'c');
        !           510:                bscpsm(dev);
        !           511:                goto brxrti;
        !           512:        }
        !           513: 
        !           514:        /* Check for HUNT mode */
        !           515:        if (bp->b_cntl & X_HUNT) {
        !           516:                if (cc != 0)    /* We get a null when hunt done */
        !           517:                        goto brxrti;
        !           518:        /*      c = spl8();     */
        !           519: 
        !           520:                /* Release command buffer */
        !           521:                /*vrelease (bp->b_devregs, bp->b_cmdbuf);*/
        !           522:                 /*     splx(c);        */
        !           523:                bp->b_cntl &= ~X_HUNT;
        !           524:                goto brxrti;
        !           525:        }
        !           526: 
        !           527:        if (bp->b_rclptr == (char *)0)  /* Is PSM waiting on us? */
        !           528:                goto brxrti;            /* no - ignore this character */
        !           529: 
        !           530:        /* Classify current data character, get new state, do action */
        !           531:        p = strlchr(bp->b_rxcls, cc, sizeof asccls);
        !           532:        if (p == (char *) 0)
        !           533:                class = 0;
        !           534:        else    class = (p - bp->b_rxcls) + 1;
        !           535: 
        !           536: 
        !           537:        stact = (clstbl[class*6 + bp->b_rxst0]) & 0xff;
        !           538: 
        !           539: #ifdef BSC_DEBUG
        !           540:        if (bscdebug & LRCVCHAR)
        !           541:                printf("\nbscrcx: (%lx)",cc & 0xff);
        !           542:        if (bscdebug & LSTATE)
        !           543:                printf("\nbscrcx: (lstate=%d)(event=%d)(nstate=%d)(act=%d)",
        !           544:                        bp->b_rxst0, class, stact >> 4, stact & 15);
        !           545: #endif
        !           546: 
        !           547:        bp->b_rxst0 = stact >> 4;       /* new state 0 */
        !           548:        switch (stact & 15) {           /* take action */
        !           549:        case 0:
        !           550:                break;
        !           551: 
        !           552:        case 1: /* Prepare to receive data */
        !           553:                bp->b_hlflgs &= ~BSC_XTRN;      /* reset transp indicator */
        !           554: act1a:         bp->b_hlflgs &= ~BSC_CRCERR;    /* reset CRC error flag */
        !           555:                bp->b_rxdptr = bp->b_buffer;            /* receive data ptr */
        !           556:                bp->b_bsize = 0;                /* data count <- 0 */
        !           557:                if (class == C0_SOH) {          /* if header, reset hptr */
        !           558:                        bp->b_rxhptr = bp->b_iocout.b_hostid;
        !           559:                        bp->b_rxhcnt = 0;
        !           560:                }
        !           561:                bp->b_crc[0] = bp->b_crc[1] = 0;        /* clear crc/lrc */
        !           562:                bp->b_cntl |= X_ACMCRC; /* set accum flag */
        !           563:                break;
        !           564: 
        !           565:        case 2: /* Save current character as heading info */
        !           566:                /* Must be 'printable' character in code set in use */
        !           567:                if (bp->b_rxhcnt < sizeof bp->b_iocout.b_hostid &&
        !           568:                    (((bp->b_hlflgs & BSCASCII) && cc >= 0x20 && cc < 0x7e) ||
        !           569:                    (!(bp->b_hlflgs& BSCASCII) && cc >= 0x40 && cc < 0xf9))) {
        !           570:                        *bp->b_rxhptr++ = (char)cc;
        !           571:                        ++bp->b_rxhcnt;
        !           572:                } else
        !           573:                        brxres(dev);
        !           574:                if (bp->b_cntl & X_ACMCRC)
        !           575:                        crccalc (1, &tc, bp);
        !           576:                break;
        !           577: 
        !           578:        case 3: /* Terminate, class = TTD */
        !           579:                bp->b_class1 = C_TTD;
        !           580:                goto brx_term;
        !           581: 
        !           582:        case 5: /* crc/lrc for IUS follows - skip processing it */
        !           583:                bp->b_class1 = C_IUS;
        !           584:                bp->b_rxcnt = (bp->b_hlflgs & BSCASCII) ? 1 : 2;
        !           585:                /* Fall through to case 4, saving IUS as data */
        !           586: 
        !           587:        case 4: /* Save current character as data */
        !           588:                crccalc (1, &tc, bp);
        !           589:                if (++bp->b_bsize <= BSCMBLK)
        !           590:                        *bp->b_rxdptr++ = (char)cc;
        !           591:                if (bp->b_trace > 1) {  /* data trace? */
        !           592:                        tc = (char)cc;
        !           593:                        bsctr(dev,bp->b_class1,'y',(short)1,&tc);
        !           594:                }
        !           595:                break;
        !           596: 
        !           597:        case 6: /* crc/lrc for ETB/ETX follows - skip processing it */
        !           598:                crccalc (1, &tc, bp);
        !           599:                bp->b_class1 = class - C0_ETX + C_ETX;
        !           600:                if (bp->b_hlflgs & BSCASCII)
        !           601:                        bp->b_rxcnt = 1;        /* Lrc for Ascii        */
        !           602:                else
        !           603:                        bp->b_rxcnt = 2;        /* 2 for crc            */
        !           604:                break;
        !           605: 
        !           606:        case 7: /* Set crc accum and transparency flag */
        !           607:                bp->b_hlflgs |= BSC_XTRN;
        !           608:                goto act1a;
        !           609: 
        !           610:        case 8: /* Terminate; NAK */
        !           611:                bp->b_class1 = C_NAK;
        !           612:                goto brx_term;
        !           613: 
        !           614:        case 9: /* Terminate; ENQ */
        !           615:                bp->b_class1 = C_ENQ;
        !           616:                goto brx_term;
        !           617: 
        !           618:        case 10:/* Terminate; EOT */
        !           619:                bp->b_class1 = C_EOT;
        !           620:                goto brx_term;
        !           621: 
        !           622:        case 11:/* Check for DLE-xxx sequence; terminate with L1 code */
        !           623:                /* if applicable, else ignore */
        !           624:                if (bp->b_hlflgs & BSCASCII) {
        !           625:                        p = strlchr(adlelst,cc,sizeof adlelst);
        !           626:                        if (p == (char *)0)
        !           627:                                break;
        !           628:                        bp->b_class1 = dlexxx[p - adlelst];
        !           629:                } else {
        !           630:                        p = strlchr(edlelst,cc,sizeof edlelst);
        !           631:                        if (p == (char *)0)
        !           632:                                break;
        !           633:                        bp->b_class1 = dlexxx[p - edlelst];
        !           634:                }
        !           635:                goto brx_term;
        !           636: 
        !           637:        case 12:/* Don't accum crc/lrc on this. */
        !           638:                bp->b_alarm = 2*PSMTPS; /* Set 2 sec. timeout           */
        !           639:                break;
        !           640:        }
        !           641: brxrti:;
        !           642: }
        !           643: 
        !           644: brxres(dev)    /* Reset Receiver (Hunt Mode) */
        !           645: dev_t dev;
        !           646: {
        !           647:        register struct bsc *bp = &bsc[dev];
        !           648:        register struct vxcmd *cp;
        !           649:        register struct vcx *xp;
        !           650:        struct vxcmd * vobtain();
        !           651:        int x = spl8();
        !           652: 
        !           653:        xp = (struct vcx *) bp->b_devregs;
        !           654:        cp = vobtain(xp);       /* Get command buffer for Hunt Command  */
        !           655:        /* splx(x); */          /* Should be after vcmd(); dn 2/27/85   */
        !           656:        cp->cmd = HUNTMD;       /* Synch. Hunt Mode Command             */
        !           657:        cp->par[0] = 0;         /* Not used                             */
        !           658:        cp->par[1] = (dev%NBSC)+xp->v_loport;   /* Port Number          */
        !           659:        vcmd(xp->v_nbr, &cp->cmd);      /* Execute Command              */
        !           660:        splx(x);
        !           661:        bp->b_cntl |= X_HUNT;
        !           662:        bp->b_crc[0] = bp->b_crc[1] = 0;        /* Reset lrc            */
        !           663:        bp->b_rxhptr = bp->b_iocout.b_hostid;   /* reset ptr for header */
        !           664:        bp->b_rxhcnt = 0;               /* Reset current header count   */
        !           665:        bp->b_rxst0 = 0;                /* Reset lvl 0 state            */
        !           666: }
        !           667: 
        !           668: char * strlchr(s,c,l)  /* locate character in string */
        !           669: register char *s, c;
        !           670: register int l;
        !           671: {      while (--l >= 0) {
        !           672:                if (*s == c)
        !           673:                        return (s);
        !           674:                ++s;
        !           675:        }
        !           676:        return (char *) 0;
        !           677: }
        !           678: 
        !           679: /*     CRC table - crc-16      */
        !           680: short crctab[] = {
        !           681:        0x0000, /* 00 */
        !           682:        0xc0c1, /* 01 */
        !           683:        0xc181, /* 02 */
        !           684:        0x0140, /* 03 */
        !           685:        0xc301, /* 04 */
        !           686:        0x03c0, /* 05 */
        !           687:        0x0280, /* 06 */
        !           688:        0xc241, /* 07 */
        !           689:        0xc601, /* 08 */
        !           690:        0x06c0, /* 09 */
        !           691:        0x0780, /* 0a */
        !           692:        0xc741, /* 0b */
        !           693:        0x0500, /* 0c */
        !           694:        0xc5c1, /* 0d */
        !           695:        0xc481, /* 0e */
        !           696:        0x0440, /* 0f */
        !           697:        0xcc01, /* 10 */
        !           698:        0x0cc0, /* 11 */
        !           699:        0x0d80, /* 12 */
        !           700:        0xcd41, /* 13 */
        !           701:        0x0f00, /* 14 */
        !           702:        0xcfc1, /* 15 */
        !           703:        0xce81, /* 16 */
        !           704:        0x0e40, /* 17 */
        !           705:        0x0a00, /* 18 */
        !           706:        0xcac1, /* 19 */
        !           707:        0xcb81, /* 1a */
        !           708:        0x0b40, /* 1b */
        !           709:        0xc901, /* 1c */
        !           710:        0x09c0, /* 1d */
        !           711:        0x0880, /* 1e */
        !           712:        0xc841, /* 1f */
        !           713:        0xd801, /* 20 */
        !           714:        0x18c0, /* 21 */
        !           715:        0x1980, /* 22 */
        !           716:        0xd941, /* 23 */
        !           717:        0x1b00, /* 24 */
        !           718:        0xdbc1, /* 25 */
        !           719:        0xda81, /* 26 */
        !           720:        0x1a40, /* 27 */
        !           721:        0x1e00, /* 28 */
        !           722:        0xdec1, /* 29 */
        !           723:        0xdf81, /* 2a */
        !           724:        0x1f40, /* 2b */
        !           725:        0xdd01, /* 2c */
        !           726:        0x1dc0, /* 2d */
        !           727:        0x1c80, /* 2e */
        !           728:        0xdc41, /* 2f */
        !           729:        0x1400, /* 30 */
        !           730:        0xd4c1, /* 31 */
        !           731:        0xd581, /* 32 */
        !           732:        0x1540, /* 33 */
        !           733:        0xd701, /* 34 */
        !           734:        0x17c0, /* 35 */
        !           735:        0x1680, /* 36 */
        !           736:        0xd641, /* 37 */
        !           737:        0xd201, /* 38 */
        !           738:        0x12c0, /* 39 */
        !           739:        0x1380, /* 3a */
        !           740:        0xd341, /* 3b */
        !           741:        0x1100, /* 3c */
        !           742:        0xd1c1, /* 3d */
        !           743:        0xd081, /* 3e */
        !           744:        0x1040, /* 3f */
        !           745:        0xf001, /* 40 */
        !           746:        0x30c0, /* 41 */
        !           747:        0x3180, /* 42 */
        !           748:        0xf141, /* 43 */
        !           749:        0x3300, /* 44 */
        !           750:        0xf3c1, /* 45 */
        !           751:        0xf281, /* 46 */
        !           752:        0x3240, /* 47 */
        !           753:        0x3600, /* 48 */
        !           754:        0xf6c1, /* 49 */
        !           755:        0xf781, /* 4a */
        !           756:        0x3740, /* 4b */
        !           757:        0xf501, /* 4c */
        !           758:        0x35c0, /* 4d */
        !           759:        0x3480, /* 4e */
        !           760:        0xf441, /* 4f */
        !           761:        0x3c00, /* 50 */
        !           762:        0xfcc1, /* 51 */
        !           763:        0xfd81, /* 52 */
        !           764:        0x3d40, /* 53 */
        !           765:        0xff01, /* 54 */
        !           766:        0x3fc0, /* 55 */
        !           767:        0x3e80, /* 56 */
        !           768:        0xfe41, /* 57 */
        !           769:        0xfa01, /* 58 */
        !           770:        0x3ac0, /* 59 */
        !           771:        0x3b80, /* 5a */
        !           772:        0xfb41, /* 5b */
        !           773:        0x3900, /* 5c */
        !           774:        0xf9c1, /* 5d */
        !           775:        0xf881, /* 5e */
        !           776:        0x3840, /* 5f */
        !           777:        0x2800, /* 60 */
        !           778:        0xe8c1, /* 61 */
        !           779:        0xe981, /* 62 */
        !           780:        0x2940, /* 63 */
        !           781:        0xeb01, /* 64 */
        !           782:        0x2bc0, /* 65 */
        !           783:        0x2a80, /* 66 */
        !           784:        0xea41, /* 67 */
        !           785:        0xee01, /* 68 */
        !           786:        0x2ec0, /* 69 */
        !           787:        0x2f80, /* 6a */
        !           788:        0xef41, /* 6b */
        !           789:        0x2d00, /* 6c */
        !           790:        0xedc1, /* 6d */
        !           791:        0xec81, /* 6e */
        !           792:        0x2c40, /* 6f */
        !           793:        0xe401, /* 70 */
        !           794:        0x24c0, /* 71 */
        !           795:        0x2580, /* 72 */
        !           796:        0xe541, /* 73 */
        !           797:        0x2700, /* 74 */
        !           798:        0xe7c1, /* 75 */
        !           799:        0xe681, /* 76 */
        !           800:        0x2640, /* 77 */
        !           801:        0x2200, /* 78 */
        !           802:        0xe2c1, /* 79 */
        !           803:        0xe381, /* 7a */
        !           804:        0x2340, /* 7b */
        !           805:        0xe101, /* 7c */
        !           806:        0x21c0, /* 7d */
        !           807:        0x2080, /* 7e */
        !           808:        0xe041, /* 7f */
        !           809:        0xa001, /* 80 */
        !           810:        0x60c0, /* 81 */
        !           811:        0x6180, /* 82 */
        !           812:        0xa141, /* 83 */
        !           813:        0x6300, /* 84 */
        !           814:        0xa3c1, /* 85 */
        !           815:        0xa281, /* 86 */
        !           816:        0x6240, /* 87 */
        !           817:        0x6600, /* 88 */
        !           818:        0xa6c1, /* 89 */
        !           819:        0xa781, /* 8a */
        !           820:        0x6740, /* 8b */
        !           821:        0xa501, /* 8c */
        !           822:        0x65c0, /* 8d */
        !           823:        0x6480, /* 8e */
        !           824:        0xa441, /* 8f */
        !           825:        0x6c00, /* 90 */
        !           826:        0xacc1, /* 91 */
        !           827:        0xad81, /* 92 */
        !           828:        0x6d40, /* 93 */
        !           829:        0xaf01, /* 94 */
        !           830:        0x6fc0, /* 95 */
        !           831:        0x6e80, /* 96 */
        !           832:        0xae41, /* 97 */
        !           833:        0xaa01, /* 98 */
        !           834:        0x6ac0, /* 99 */
        !           835:        0x6b80, /* 9a */
        !           836:        0xab41, /* 9b */
        !           837:        0x6900, /* 9c */
        !           838:        0xa9c1, /* 9d */
        !           839:        0xa881, /* 9e */
        !           840:        0x6840, /* 9f */
        !           841:        0x7800, /* a0 */
        !           842:        0xb8c1, /* a1 */
        !           843:        0xb981, /* a2 */
        !           844:        0x7940, /* a3 */
        !           845:        0xbb01, /* a4 */
        !           846:        0x7bc0, /* a5 */
        !           847:        0x7a80, /* a6 */
        !           848:        0xba41, /* a7 */
        !           849:        0xbe01, /* a8 */
        !           850:        0x7ec0, /* a9 */
        !           851:        0x7f80, /* aa */
        !           852:        0xbf41, /* ab */
        !           853:        0x7d00, /* ac */
        !           854:        0xbdc1, /* ad */
        !           855:        0xbc81, /* ae */
        !           856:        0x7c40, /* af */
        !           857:        0xb401, /* b0 */
        !           858:        0x74c0, /* b1 */
        !           859:        0x7580, /* b2 */
        !           860:        0xb541, /* b3 */
        !           861:        0x7700, /* b4 */
        !           862:        0xb7c1, /* b5 */
        !           863:        0xb681, /* b6 */
        !           864:        0x7640, /* b7 */
        !           865:        0x7200, /* b8 */
        !           866:        0xb2c1, /* b9 */
        !           867:        0xb381, /* ba */
        !           868:        0x7340, /* bb */
        !           869:        0xb101, /* bc */
        !           870:        0x71c0, /* bd */
        !           871:        0x7080, /* be */
        !           872:        0xb041, /* bf */
        !           873:        0x5000, /* c0 */
        !           874:        0x90c1, /* c1 */
        !           875:        0x9181, /* c2 */
        !           876:        0x5140, /* c3 */
        !           877:        0x9301, /* c4 */
        !           878:        0x53c0, /* c5 */
        !           879:        0x5280, /* c6 */
        !           880:        0x9241, /* c7 */
        !           881:        0x9601, /* c8 */
        !           882:        0x56c0, /* c9 */
        !           883:        0x5780, /* ca */
        !           884:        0x9741, /* cb */
        !           885:        0x5500, /* cc */
        !           886:        0x95c1, /* cd */
        !           887:        0x9481, /* ce */
        !           888:        0x5440, /* cf */
        !           889:        0x9c01, /* d0 */
        !           890:        0x5cc0, /* d1 */
        !           891:        0x5d80, /* d2 */
        !           892:        0x9d41, /* d3 */
        !           893:        0x5f00, /* d4 */
        !           894:        0x9fc1, /* d5 */
        !           895:        0x9e81, /* d6 */
        !           896:        0x5e40, /* d7 */
        !           897:        0x5a00, /* d8 */
        !           898:        0x9ac1, /* d9 */
        !           899:        0x9b81, /* da */
        !           900:        0x5b40, /* db */
        !           901:        0x9901, /* dc */
        !           902:        0x59c0, /* dd */
        !           903:        0x5880, /* de */
        !           904:        0x9841, /* df */
        !           905:        0x8801, /* e0 */
        !           906:        0x48c0, /* e1 */
        !           907:        0x4980, /* e2 */
        !           908:        0x8941, /* e3 */
        !           909:        0x4b00, /* e4 */
        !           910:        0x8bc1, /* e5 */
        !           911:        0x8a81, /* e6 */
        !           912:        0x4a40, /* e7 */
        !           913:        0x4e00, /* e8 */
        !           914:        0x8ec1, /* e9 */
        !           915:        0x8f81, /* ea */
        !           916:        0x4f40, /* eb */
        !           917:        0x8d01, /* ec */
        !           918:        0x4dc0, /* ed */
        !           919:        0x4c80, /* ee */
        !           920:        0x8c41, /* ef */
        !           921:        0x4400, /* f0 */
        !           922:        0x84c1, /* f1 */
        !           923:        0x8581, /* f2 */
        !           924:        0x4540, /* f3 */
        !           925:        0x8701, /* f4 */
        !           926:        0x47c0, /* f5 */
        !           927:        0x4680, /* f6 */
        !           928:        0x8641, /* f7 */
        !           929:        0x8201, /* f8 */
        !           930:        0x42c0, /* f9 */
        !           931:        0x4380, /* fa */
        !           932:        0x8341, /* fb */
        !           933:        0x4100, /* fc */
        !           934:        0x81c1, /* fd */
        !           935:        0x8081, /* fe */
        !           936:        0x4040, /* ff */
        !           937:        };
        !           938: 
        !           939: crccalc(count, buffer, bp)
        !           940: register int count;
        !           941: register char *buffer;
        !           942: struct bsc *bp;
        !           943: {
        !           944:        register unsigned int work, crc;
        !           945: 
        !           946:        crc = ((bp->b_crc[1] & 0xff)<<8) | (bp->b_crc[0] & 0xff);
        !           947:        if (bp->b_hlflgs & BSCASCII)
        !           948:                while (--count >= 0)    {
        !           949:                        work = (*buffer++) & 0xff;
        !           950:                        crc ^= work | (work << 8);
        !           951:                }
        !           952:        else
        !           953:                while (--count >= 0)    {
        !           954:                        work = crctab[0xff & (crc ^ *buffer++)];
        !           955:                        crc = (work & 0xff00) |
        !           956:                              (0xff & ((crc >> 8) ^ work));
        !           957:                }
        !           958:        bp->b_crc[0] = crc;
        !           959:        bp->b_crc[1] = crc >> 8;
        !           960: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.