Annotation of Gnu-Mach/chips/scc_8530_hdw.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1993-1989 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     File: scc_8530_hdw.c
        !            28:  *     Author: Alessandro Forin, Carnegie Mellon University
        !            29:  *     Date:   6/91
        !            30:  *
        !            31:  *     Hardware-level operations for the SCC Serial Line Driver
        !            32:  */
        !            33: 
        !            34: #include <scc.h>
        !            35: #if    NSCC > 0
        !            36: #include <bm.h>
        !            37: #include <platforms.h>
        !            38: 
        !            39: #include <mach_kdb.h>
        !            40: 
        !            41: #include <machine/machspl.h>           /* spl definitions */
        !            42: #include <mach/std_types.h>
        !            43: #include <device/io_req.h>
        !            44: #include <device/tty.h>
        !            45: 
        !            46: #include <chips/busses.h>
        !            47: #include <chips/serial_defs.h>
        !            48: #include <chips/screen_defs.h>
        !            49: 
        !            50: /* Alignment and padding */
        !            51: #if    defined(DECSTATION)
        !            52: /*
        !            53:  * 3min's padding
        !            54:  */
        !            55: typedef struct {
        !            56:        char                    pad0;
        !            57:        volatile unsigned char  datum;
        !            58:        char                    pad1[2];
        !            59: } scc_padded1_register_t;
        !            60: 
        !            61: #define        scc_register_t  scc_padded1_register_t
        !            62: #endif
        !            63: 
        !            64: #if    defined(FLAMINGO)
        !            65: typedef struct {
        !            66:        volatile unsigned int   datum;
        !            67:        unsigned int            pad1;
        !            68: } scc_padded1_register_t;
        !            69: 
        !            70: #define        scc_register_t  scc_padded1_register_t
        !            71: 
        !            72: #define        scc_set_datum(d,v)      (d) = (volatile unsigned int) (v) << 8, wbflush()
        !            73: #define        scc_get_datum(d,v)      (v) = ((d) >> 8) & 0xff
        !            74: 
        !            75: #endif
        !            76: 
        !            77: #include <chips/scc_8530.h>    /* needs the above defs */
        !            78: 
        !            79: #define private static
        !            80: #define public
        !            81: 
        !            82: /*
        !            83:  * Forward decls
        !            84:  */
        !            85: private check_car( struct tty *, boolean_t );
        !            86: 
        !            87: /*
        !            88:  * On the 3min keyboard and mouse come in on channels A
        !            89:  * of the two units.  The MI code expects them at 'lines'
        !            90:  * 0 and 1, respectively.  So we map here back and forth.
        !            91:  * Note also the MI code believes unit 0 has four lines.
        !            92:  */
        !            93: 
        !            94: #define        SCC_KBDUNIT     1
        !            95: #define        SCC_PTRUNIT     0
        !            96: 
        !            97: mi_to_scc(unitp, linep)
        !            98:        int     *unitp, *linep;
        !            99: {
        !           100:        /* only play games on MI 'unit' 0 */
        !           101:        if (*unitp) {
        !           102:                /* e.g. by mapping the first four lines specially */
        !           103:                *unitp++;
        !           104:                return;
        !           105:        }
        !           106: 
        !           107:        /* always get unit=0 (console) and line = 0|1 */
        !           108:        if (*linep == SCREEN_LINE_KEYBOARD) {
        !           109:                *unitp = SCC_KBDUNIT;
        !           110:                *linep = SCC_CHANNEL_A;
        !           111:        } else if (*linep == SCREEN_LINE_POINTER) {
        !           112:                *unitp = SCC_PTRUNIT;
        !           113:                *linep = SCC_CHANNEL_A;
        !           114:        } else {
        !           115:                *unitp = (*linep & 1);
        !           116:                *linep = SCC_CHANNEL_B;
        !           117:        }
        !           118: /* line 0 is channel B, line 1 is channel A */
        !           119: }
        !           120: 
        !           121: #define        NSCC_LINE       2       /* 2 ttys per chip */
        !           122: 
        !           123: /* only care for mapping to ttyno */
        !           124: scc_to_mi(sccunit, sccline)
        !           125: {
        !           126:        if (sccunit > 1)
        !           127:                return (sccunit * NSCC_LINE + sccline);
        !           128:        /* only for console (first pair of SCCs): */
        !           129:        if (sccline == SCC_CHANNEL_A)
        !           130:                return ((!sccunit) & 1);
        !           131:        return 2+sccunit;
        !           132: }
        !           133: 
        !           134: 
        !           135: /*
        !           136:  * Driver status
        !           137:  */
        !           138: struct scc_softc {
        !           139:        scc_regmap_t    *regs;
        !           140: 
        !           141:        /* software copy of some write regs, for reg |= */
        !           142:        struct softreg {
        !           143:                unsigned char   wr1;
        !           144:                unsigned char   wr4;
        !           145:                unsigned char   wr5;
        !           146:                unsigned char   wr14;
        !           147:        } softr[2];     /* per channel */
        !           148: 
        !           149:        unsigned char   last_rr0[2];    /* for modem signals */
        !           150:        unsigned short  fake;   /* missing rs232 bits, channel A */
        !           151:        char            polling_mode;
        !           152:        char            softCAR, osoftCAR;
        !           153:        char            probed_once;
        !           154: 
        !           155:        boolean_t       full_modem;
        !           156:        boolean_t       isa_console;
        !           157: 
        !           158: } scc_softc_data[NSCC];
        !           159: 
        !           160: typedef struct scc_softc *scc_softc_t;
        !           161: 
        !           162: scc_softc_t    scc_softc[NSCC];
        !           163: 
        !           164: scc_softCAR(unit, line, on)
        !           165: {
        !           166:        mi_to_scc(&unit, &line);
        !           167:        if (on)
        !           168:                scc_softc[unit]->softCAR |= 1<<line;
        !           169:        else
        !           170:                scc_softc[unit]->softCAR &= ~(1 << line);
        !           171: }
        !           172: 
        !           173: 
        !           174: /*
        !           175:  * BRG formula is:
        !           176:  *                             ClockFrequency
        !           177:  *     BRGconstant =   ---------------------------  -  2
        !           178:  *                     2 * BaudRate * ClockDivider
        !           179:  */
        !           180: /* Speed selections with Pclk=7.3728Mhz, clock x16 */
        !           181: static
        !           182: short  scc_speeds[] =
        !           183:        /* 0   50    75    110  134.5  150  200   300  600 1200 1800 2400 */
        !           184:        {  0, 4606, 3070, 2093, 1711, 1534, 1150, 766, 382, 190, 126, 94,
        !           185: 
        !           186:        /* 4800 9600 19.2k 38.4k */
        !           187:          46,   22,  10,    4};
        !           188: 
        !           189: /*
        !           190:  * Definition of the driver for the auto-configuration program.
        !           191:  */
        !           192: 
        !           193: int    scc_probe(), scc_intr();
        !           194: static void scc_attach();
        !           195: 
        !           196: vm_offset_t    scc_std[NSCC] = { 0 };
        !           197: struct bus_device *scc_info[NSCC];
        !           198: struct bus_driver scc_driver = 
        !           199:         { scc_probe, 0, scc_attach, 0, scc_std, "scc", scc_info,};
        !           200: 
        !           201: /*
        !           202:  * Adapt/Probe/Attach functions
        !           203:  */
        !           204: boolean_t              scc_uses_modem_control = FALSE;/* patch this with adb */
        !           205: 
        !           206: set_scc_address(
        !           207:        int             sccunit,
        !           208:        vm_offset_t     regs,
        !           209:        boolean_t       has_modem,
        !           210:        boolean_t       isa_console)
        !           211: {
        !           212:        extern int      scc_probe(), scc_param(), scc_start(),
        !           213:                        scc_putc(), scc_getc(),
        !           214:                        scc_pollc(), scc_mctl(), scc_softCAR();
        !           215: 
        !           216:        scc_std[sccunit] = regs;
        !           217:        scc_softc_data[sccunit].full_modem = has_modem & scc_uses_modem_control;
        !           218:        scc_softc_data[sccunit].isa_console = isa_console;
        !           219: 
        !           220:        /* Do this here */
        !           221:        console_probe           = scc_probe;
        !           222:        console_param           = scc_param;
        !           223:        console_start           = scc_start;
        !           224:        console_putc            = scc_putc;
        !           225:        console_getc            = scc_getc;
        !           226:        console_pollc           = scc_pollc;
        !           227:        console_mctl            = scc_mctl;
        !           228:        console_softCAR         = scc_softCAR;
        !           229: 
        !           230: }
        !           231: 
        !           232: scc_probe(
        !           233:        int               xxx,
        !           234:        struct bus_device *ui)
        !           235: {
        !           236:        int             sccunit = ui->unit;
        !           237:        scc_softc_t     scc;
        !           238:        register int    val;
        !           239:        register scc_regmap_t   *regs;
        !           240: 
        !           241:        regs = (scc_regmap_t *)scc_std[sccunit];
        !           242:        if (regs == 0)
        !           243:                return 0;
        !           244: 
        !           245:        /*
        !           246:         * See if we are here
        !           247:         */
        !           248:        if (check_memory(regs, 0)) {
        !           249:                /* no rides today */
        !           250:                return 0;
        !           251:        }
        !           252: 
        !           253:        scc = &scc_softc_data[sccunit];
        !           254: 
        !           255:        if (scc->probed_once++){
        !           256:                return 1;
        !           257:        }
        !           258:        /*
        !           259:         * Chip once-only initialization
        !           260:         *
        !           261:         * NOTE: The wiring we assume is the one on the 3min:
        !           262:         *
        !           263:         *      out     A-TxD   -->     TxD     keybd or mouse
        !           264:         *      in      A-RxD   -->     RxD     keybd or mouse
        !           265:         *      out     A-DTR~  -->     DTR     comm
        !           266:         *      out     A-RTS~  -->     RTS     comm
        !           267:         *      in      A-CTS~  -->     SI      comm
        !           268:         *      in      A-DCD~  -->     RI      comm
        !           269:         *      in      A-SYNCH~-->     DSR     comm
        !           270:         *      out     B-TxD   -->     TxD     comm
        !           271:         *      in      B-RxD   -->     RxD     comm
        !           272:         *      in      B-RxC   -->     TRxCB   comm
        !           273:         *      in      B-TxC   -->     RTxCB   comm
        !           274:         *      out     B-RTS~  -->     SS      comm
        !           275:         *      in      B-CTS~  -->     CTS     comm
        !           276:         *      in      B-DCD~  -->     CD      comm
        !           277:         */
        !           278: 
        !           279:        scc_softc[sccunit] = scc;
        !           280:        scc->regs = regs;
        !           281: 
        !           282:        scc->fake = 1<<SCC_CHANNEL_A;
        !           283: 
        !           284:        { 
        !           285:                register int i;
        !           286:                /* We need this in scc_start only, hence the funny
        !           287:                   value: we need it non-zero and we want to avoid
        !           288:                   too much overhead in getting to (scc,regs,line) */
        !           289:                for (i = 0; i < NSCC_LINE; i++) {
        !           290:                        register struct tty     *tp;
        !           291: 
        !           292:                        tp = console_tty[scc_to_mi(sccunit,i)];
        !           293:                        tp->t_addr = (char*)(0x80000000L + (sccunit<<1) + (i&1));
        !           294:                        /* do min buffering */
        !           295:                        tp->t_state |= TS_MIN;
        !           296:                }
        !           297:        }
        !           298: 
        !           299:        /* make sure reg pointer is in known state */
        !           300:        scc_init_reg(regs, SCC_CHANNEL_A);
        !           301:        scc_init_reg(regs, SCC_CHANNEL_B);
        !           302: 
        !           303:        /* reset chip, fully */
        !           304:        scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, SCC_WR9_HW_RESET);
        !           305:        delay(50000);/*enough ? */
        !           306:        scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, 0);
        !           307: 
        !           308:        /* program the interrupt vector */
        !           309:        scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR2, 0xf0);
        !           310:        scc_write_reg(regs, SCC_CHANNEL_B, SCC_WR2, 0xf0);
        !           311:        scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR9, SCC_WR9_VIS);
        !           312: 
        !           313:        /* most of the init is in scc_param() */
        !           314: 
        !           315:        /* timing base defaults */
        !           316:        scc->softr[SCC_CHANNEL_A].wr4 = SCC_WR4_CLK_x16;
        !           317:        scc->softr[SCC_CHANNEL_B].wr4 = SCC_WR4_CLK_x16;
        !           318: 
        !           319:        /* enable DTR, RTS and dont SS */
        !           320: #if    0
        !           321:        /* According to one book I have this signal (pin 23, "SS")
        !           322:           is "specified by the provider", meaning the EIA-232-D
        !           323:           standard does not define what it is.  Better leave
        !           324:           it alone */
        !           325:        scc->softr[SCC_CHANNEL_B].wr5 = SCC_WR5_RTS;
        !           326: #else
        !           327:        scc->softr[SCC_CHANNEL_B].wr5 = 0;
        !           328: #endif
        !           329:        scc->softr[SCC_CHANNEL_A].wr5 = SCC_WR5_RTS | SCC_WR5_DTR;
        !           330: 
        !           331:        /* baud rates */
        !           332:        val = SCC_WR14_BAUDR_ENABLE|SCC_WR14_BAUDR_SRC;
        !           333:        scc->softr[SCC_CHANNEL_B].wr14 = val;
        !           334:        scc->softr[SCC_CHANNEL_A].wr14 = val;
        !           335: 
        !           336:        /* interrupt conditions */
        !           337:        val =   SCC_WR1_RXI_ALL_CHAR | SCC_WR1_PARITY_IE |
        !           338:                SCC_WR1_EXT_IE | SCC_WR1_TX_IE;         
        !           339:        scc->softr[SCC_CHANNEL_A].wr1 = val;
        !           340:        scc->softr[SCC_CHANNEL_B].wr1 = val;
        !           341: 
        !           342:        scc_read_reg_zero(regs, SCC_CHANNEL_A, scc->last_rr0[SCC_CHANNEL_A]);
        !           343:        scc_read_reg_zero(regs, SCC_CHANNEL_B, scc->last_rr0[SCC_CHANNEL_B]);
        !           344: 
        !           345:        /*
        !           346:         * After probing, any line that should be active
        !           347:         * (keybd,mouse,rcline) is activated via scc_param().
        !           348:         */
        !           349: 
        !           350:        scc_set_modem_control(scc, scc->full_modem);
        !           351: 
        !           352: #if defined(KMIN) || defined (FLAMINGO) || defined(KN03)
        !           353:        /*
        !           354:         * Crock: MI code knows of unit 0 as console, we need
        !           355:         * unit 1 as well since the keyboard is there
        !           356:         * This is acceptable on maxine, which has to call its
        !           357:         * only one chip unit 1 so that rconsole is happy.
        !           358:         */
        !           359:        if (sccunit == 0) {
        !           360:                struct bus_device d;
        !           361:                d = *ui;
        !           362:                d.unit = 1;
        !           363:                scc_probe( xxx, &d);
        !           364:        }
        !           365: #endif
        !           366:        return 1;
        !           367: }
        !           368: 
        !           369: boolean_t scc_timer_started = FALSE;
        !           370: 
        !           371: static void
        !           372: scc_attach(
        !           373:        register struct bus_device *ui)
        !           374: {
        !           375:        int sccunit = ui->unit;
        !           376:        extern scc_scan();
        !           377:        extern int tty_inq_size;
        !           378:        int i;
        !           379: 
        !           380:        /* We only have 4 ttys, but always at 9600
        !           381:         * Give em a lot of room (plus dma..)
        !           382:         */
        !           383:        tty_inq_size = 4096;
        !           384:        if (!scc_timer_started) {
        !           385:                /* do all of them, before we call scc_scan() */
        !           386:                /* harmless if done already */
        !           387:                for (i = 0; i < NSCC*NSCC_LINE; i++)
        !           388:                        ttychars(console_tty[i]);
        !           389: 
        !           390:                scc_timer_started = TRUE;
        !           391:                scc_scan();
        !           392:        }
        !           393: 
        !           394: #if    NBM > 0
        !           395:        if (SCREEN_ISA_CONSOLE() && scc_softc[sccunit]->isa_console) {
        !           396:                printf("\n sl0: ");
        !           397:                if (sccunit && rcline == 3) printf("( rconsole )");
        !           398: 
        !           399:                if (sccunit == SCC_KBDUNIT) {
        !           400:                        printf("\n sl1: "); lk201_attach(0, sccunit >> 1);
        !           401:                } else if (sccunit == SCC_PTRUNIT) {
        !           402:                        printf("\n sl1: "); mouse_attach(0, sccunit >> 1);
        !           403:                }
        !           404:        } else
        !           405: #endif /*NBM > 0*/
        !           406:        {
        !           407:                printf("%s", (sccunit == 1) ?
        !           408:                        "\n sl0: ( alternate console )\n sl1:" :
        !           409:                        "\n sl0:\n sl1:");
        !           410:        }
        !           411: }
        !           412: 
        !           413: /*
        !           414:  * Would you like to make a phone call ?
        !           415:  */
        !           416: scc_set_modem_control(
        !           417:        scc_softc_t     scc,
        !           418:        boolean_t       on)
        !           419: {
        !           420:        if (on)
        !           421:                /* your problem if the hardware then is broke */
        !           422:                scc->fake = 0;
        !           423:        else
        !           424:                scc->fake = 3;
        !           425:        scc->full_modem = on;
        !           426:        /* user should do an scc_param() ifchanged */
        !           427: }
        !           428: 
        !           429: /*
        !           430:  * Polled I/O (debugger)
        !           431:  */
        !           432: scc_pollc(
        !           433:        int                     unit,
        !           434:        boolean_t               on)
        !           435: {
        !           436:        scc_softc_t             scc;
        !           437:        int                     line = SCREEN_LINE_KEYBOARD,
        !           438:                                sccunit = unit;
        !           439: 
        !           440:        mi_to_scc(&sccunit, &line);
        !           441: 
        !           442:        scc = scc_softc[sccunit];
        !           443:        if (on) {
        !           444:                scc->polling_mode++;
        !           445: #if    NBM > 0
        !           446:                screen_on_off(unit, TRUE);
        !           447: #endif NBM > 0
        !           448:        } else
        !           449:                scc->polling_mode--;
        !           450: }
        !           451: 
        !           452: /*
        !           453:  * Interrupt routine
        !           454:  */
        !           455: int scc_intr_count;
        !           456: 
        !           457: scc_intr(
        !           458:        int     unit,
        !           459:        spl_t   spllevel)
        !           460: {
        !           461:        scc_softc_t             scc = scc_softc[unit];
        !           462:        register scc_regmap_t   *regs = scc->regs;
        !           463:        register int            rr1, rr2;
        !           464:        register int            c;
        !           465: 
        !           466: scc_intr_count++;
        !           467: 
        !           468: #if    mips
        !           469:        splx(spllevel);         /* lower priority */
        !           470: #endif
        !           471: 
        !           472:        while (1) {
        !           473: 
        !           474:          scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR2, rr2);
        !           475: 
        !           476:          rr2 = SCC_RR2_STATUS(rr2);
        !           477: 
        !           478:          /* are we done yet ? */
        !           479:          if (rr2 == 6) {       /* strange, distinguished value */
        !           480:                register int rr3;
        !           481:                scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR3, rr3);
        !           482:                if (rr3 == 0)
        !           483:                        return;
        !           484:          }
        !           485: 
        !           486:          if ((rr2 == SCC_RR2_A_XMIT_DONE) || (rr2 == SCC_RR2_B_XMIT_DONE)) {
        !           487: 
        !           488:                register chan = (rr2 == SCC_RR2_A_XMIT_DONE) ?
        !           489:                                        SCC_CHANNEL_A : SCC_CHANNEL_B;
        !           490: 
        !           491:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           492:                c = cons_simple_tint(scc_to_mi(unit,chan), FALSE);
        !           493: 
        !           494:                if (c == -1) {
        !           495:                        /* no more data for this line */
        !           496: 
        !           497:                        scc_read_reg(regs, chan, SCC_RR15, c);
        !           498:                        c &= ~SCC_WR15_TX_UNDERRUN_IE;
        !           499:                        scc_write_reg(regs, chan, SCC_WR15, c);
        !           500: 
        !           501:                        c = scc->softr[chan].wr1 & ~SCC_WR1_TX_IE;
        !           502:                        scc_write_reg(regs, chan, SCC_WR1, c);
        !           503:                        scc->softr[chan].wr1 = c;
        !           504: 
        !           505:                        c = cons_simple_tint(scc_to_mi(unit,chan), TRUE);
        !           506:                        if (c != -1)
        !           507:                                /* funny race, scc_start has been called already */
        !           508:                                scc_write_data(regs, chan, c);
        !           509:                } else {
        !           510:                        scc_write_data(regs, chan, c);
        !           511:                        /* and leave it enabled */
        !           512:                }
        !           513:          }
        !           514: 
        !           515:          else if (rr2 == SCC_RR2_A_RECV_DONE) {
        !           516:                int     err = 0;
        !           517: 
        !           518:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           519:                if (scc->polling_mode)
        !           520:                        continue;
        !           521: 
        !           522:                scc_read_data(regs, SCC_CHANNEL_A, c);
        !           523:                rr1 = scc_to_mi(unit,SCC_CHANNEL_A);
        !           524:                cons_simple_rint (rr1, rr1, c, 0);
        !           525:          }
        !           526: 
        !           527:          else if (rr2 == SCC_RR2_B_RECV_DONE) {
        !           528:                int     err = 0;
        !           529: 
        !           530:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           531:                if (scc->polling_mode)
        !           532:                        continue;
        !           533: 
        !           534:                scc_read_data(regs, SCC_CHANNEL_B, c);
        !           535:                rr1 = scc_to_mi(unit,SCC_CHANNEL_B);
        !           536:                cons_simple_rint (rr1, rr1, c, 0);
        !           537:          }
        !           538: 
        !           539:          else if ((rr2 == SCC_RR2_A_EXT_STATUS) || (rr2 == SCC_RR2_B_EXT_STATUS)) {
        !           540:                int chan = (rr2 == SCC_RR2_A_EXT_STATUS) ?
        !           541:                        SCC_CHANNEL_A : SCC_CHANNEL_B;
        !           542:                scc_write_reg(regs, chan, SCC_RR0, SCC_RESET_EXT_IP);
        !           543:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           544:                scc_modem_intr(scc, chan, unit);
        !           545:          }
        !           546: 
        !           547:          else if ((rr2 == SCC_RR2_A_RECV_SPECIAL) || (rr2 == SCC_RR2_B_RECV_SPECIAL)) {
        !           548:                register int chan = (rr2 == SCC_RR2_A_RECV_SPECIAL) ?
        !           549:                        SCC_CHANNEL_A : SCC_CHANNEL_B;
        !           550: 
        !           551:                scc_read_reg(regs, chan, SCC_RR1, rr1);
        !           552:                if (rr1 & (SCC_RR1_PARITY_ERR | SCC_RR1_RX_OVERRUN | SCC_RR1_FRAME_ERR)) {
        !           553:                        int err;
        !           554:                        /* map to CONS_ERR_xxx MI error codes */
        !           555:                        err =   ((rr1 & SCC_RR1_PARITY_ERR)<<8) |
        !           556:                                ((rr1 & SCC_RR1_RX_OVERRUN)<<9) |
        !           557:                                ((rr1 & SCC_RR1_FRAME_ERR)<<7);
        !           558:                        scc_write_reg(regs, chan, SCC_RR0, SCC_RESET_ERROR);
        !           559:                        rr1 = scc_to_mi(unit,chan);
        !           560:                        cons_simple_rint(rr1, rr1, 0, err);
        !           561:                }
        !           562:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           563:          }
        !           564: 
        !           565:        }
        !           566: 
        !           567: }
        !           568: 
        !           569: boolean_t
        !           570: scc_start(
        !           571:        struct tty *tp)
        !           572: {
        !           573:        register scc_regmap_t   *regs;
        !           574:        register int            chan, temp;
        !           575:        register struct softreg *sr;
        !           576: 
        !           577:        temp = (natural_t)tp->t_addr;
        !           578:        chan = (temp & 1);      /* channel */
        !           579:        temp = (temp >> 1)&0xff;/* sccunit */
        !           580:        regs = scc_softc[temp]->regs;
        !           581:        sr   = &scc_softc[temp]->softr[chan];
        !           582: 
        !           583:        scc_read_reg(regs, chan, SCC_RR15, temp);
        !           584:        temp |= SCC_WR15_TX_UNDERRUN_IE;
        !           585:        scc_write_reg(regs, chan, SCC_WR15, temp);
        !           586: 
        !           587:        temp = sr->wr1 | SCC_WR1_TX_IE;
        !           588:        scc_write_reg(regs, chan, SCC_WR1, temp);
        !           589:        sr->wr1 = temp;
        !           590: 
        !           591:        /* but we need a first char out or no cookie */
        !           592:        scc_read_reg(regs, chan, SCC_RR0, temp);
        !           593:        if (temp & SCC_RR0_TX_EMPTY)
        !           594:        {
        !           595:                register char   c;
        !           596: 
        !           597:                c = getc(&tp->t_outq);
        !           598:                scc_write_data(regs, chan, c);
        !           599:        }
        !           600: }
        !           601: 
        !           602: /*
        !           603:  * Get a char from a specific SCC line
        !           604:  * [this is only used for console&screen purposes]
        !           605:  */
        !           606: scc_getc(
        !           607:        int             unit,
        !           608:        int             line,
        !           609:        boolean_t       wait,
        !           610:        boolean_t       raw)
        !           611: {
        !           612:        scc_softc_t     scc;
        !           613:        register scc_regmap_t *regs;
        !           614:        unsigned char   c;
        !           615:        int             value, mi_line, rcvalue, from_line;
        !           616: 
        !           617:        mi_line = line;
        !           618:        mi_to_scc(&unit, &line);
        !           619: 
        !           620:        scc = scc_softc[unit];
        !           621:        regs = scc->regs;
        !           622: 
        !           623:        /*
        !           624:         * wait till something available
        !           625:         *
        !           626:         * NOTE: we know! that rcline==3
        !           627:         */
        !           628:        if (rcline) rcline = 3;
        !           629: again:
        !           630:        rcvalue = 0;
        !           631:        while (1) {
        !           632:                scc_read_reg_zero(regs, line, value);
        !           633:                if (rcline && (mi_line == SCREEN_LINE_KEYBOARD)) {
        !           634:                        scc_read_reg_zero(regs, SCC_CHANNEL_B, rcvalue);
        !           635:                        value |= rcvalue;
        !           636:                }
        !           637:                if (((value & SCC_RR0_RX_AVAIL) == 0) && wait)
        !           638:                        delay(10);
        !           639:                else
        !           640:                        break;
        !           641:        }
        !           642: 
        !           643:        /*
        !           644:         * if nothing found return -1 
        !           645:         */
        !           646:        from_line = (rcvalue & SCC_RR0_RX_AVAIL) ? SCC_CHANNEL_B : line;
        !           647: 
        !           648:        if (value & SCC_RR0_RX_AVAIL) {
        !           649:                scc_read_reg(regs, from_line, SCC_RR1, value);
        !           650:                scc_read_data(regs, from_line, c);
        !           651:        } else {
        !           652: /*             splx(s);*/
        !           653:                return -1;
        !           654:        }
        !           655: 
        !           656:        /*
        !           657:         * bad chars not ok 
        !           658:         */
        !           659:        if (value&(SCC_RR1_PARITY_ERR | SCC_RR1_RX_OVERRUN | SCC_RR1_FRAME_ERR)) {
        !           660: /* scc_state(unit,from_line); */
        !           661:                scc_write_reg(regs, from_line, SCC_RR0, SCC_RESET_ERROR);
        !           662:                if (wait) {
        !           663:                        scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           664:                        goto again;
        !           665:                }
        !           666:        }
        !           667:        scc_write_reg(regs, SCC_CHANNEL_A, SCC_RR0, SCC_RESET_HIGHEST_IUS);
        !           668: /*     splx(s);*/
        !           669: 
        !           670: 
        !           671: #if    NBM > 0
        !           672:        if ((mi_line == SCREEN_LINE_KEYBOARD) && (from_line == SCC_CHANNEL_A) &&
        !           673:            !raw && SCREEN_ISA_CONSOLE() && scc->isa_console)
        !           674:                return lk201_rint(SCREEN_CONS_UNIT(), c, wait, scc->polling_mode);
        !           675:        else
        !           676: #endif NBM > 0
        !           677:                return c;
        !           678: }
        !           679: 
        !           680: /*
        !           681:  * Put a char on a specific SCC line
        !           682:  */
        !           683: scc_putc(
        !           684:        int     unit,
        !           685:        int     line,
        !           686:        int     c)
        !           687: {
        !           688:        scc_softc_t      scc;
        !           689:        register scc_regmap_t *regs;
        !           690:        spl_t             s = spltty();
        !           691:        register int    value;
        !           692: 
        !           693:        mi_to_scc(&unit, &line);
        !           694: 
        !           695:        scc = scc_softc[unit];
        !           696:        regs = scc->regs;
        !           697: 
        !           698:        do {
        !           699:                scc_read_reg(regs, line, SCC_RR0, value);
        !           700:                if (value & SCC_RR0_TX_EMPTY)
        !           701:                        break;
        !           702:                delay(100);
        !           703:        } while (1);
        !           704: 
        !           705:        scc_write_data(regs, line, c);
        !           706: /* wait for it to swallow the char ? */
        !           707: 
        !           708:        splx(s);
        !           709: }
        !           710: 
        !           711: scc_param(
        !           712:        struct tty      *tp,
        !           713:        int             line)
        !           714: {
        !           715:        scc_regmap_t    *regs;
        !           716:        int             value, sccline, unit;
        !           717:        struct softreg  *sr;
        !           718:        scc_softc_t     scc;
        !           719:  
        !           720:        line = tp->t_dev;
        !           721:        /* MI code wants us to handle 4 lines on unit 0 */
        !           722:        unit = (line < 4) ? 0 : (line / NSCC_LINE);
        !           723:        sccline = line;
        !           724:        mi_to_scc(&unit, &sccline);
        !           725: 
        !           726:        if ((scc = scc_softc[unit]) == 0) return;       /* sanity */
        !           727:        regs = scc->regs;
        !           728: 
        !           729:        sr = &scc->softr[sccline];
        !           730: 
        !           731:        /*
        !           732:         * Do not let user fool around with kbd&mouse
        !           733:         */
        !           734: #if    NBM > 0
        !           735:        if (screen_captures(line)) {
        !           736:                tp->t_ispeed = tp->t_ospeed = B4800;
        !           737:                tp->t_flags |= TF_LITOUT;
        !           738:        }
        !           739: #endif NBM > 0
        !           740: 
        !           741:        if (tp->t_ispeed == 0) {
        !           742:                (void) scc_mctl(tp->t_dev, TM_HUP, DMSET);      /* hang up line */
        !           743:                return;
        !           744:        }
        !           745: 
        !           746:        /* reset line */
        !           747:        value = (sccline == SCC_CHANNEL_A) ? SCC_WR9_RESET_CHA_A : SCC_WR9_RESET_CHA_B;
        !           748:        scc_write_reg(regs, sccline, SCC_WR9, value);
        !           749:        delay(25);
        !           750: 
        !           751:        /* stop bits, normally 1 */
        !           752:        value = sr->wr4 & 0xf0;
        !           753:        value |= (tp->t_ispeed == B110) ? SCC_WR4_2_STOP : SCC_WR4_1_STOP;
        !           754: 
        !           755:        /* .. and parity */
        !           756:        if ((tp->t_flags & (TF_ODDP | TF_EVENP)) == TF_ODDP)
        !           757:                value |= SCC_WR4_PARITY_ENABLE;
        !           758: 
        !           759:        /* set it now, remember it must be first after reset */
        !           760:        sr->wr4 = value;
        !           761:        scc_write_reg(regs, sccline, SCC_WR4, value);
        !           762: 
        !           763:        /* vector again */
        !           764:        scc_write_reg(regs, sccline, SCC_WR2, 0xf0);
        !           765: 
        !           766:        /* we only do 8 bits per char */
        !           767:        value = SCC_WR3_RX_8_BITS;
        !           768:        scc_write_reg(regs, sccline, SCC_WR3, value);
        !           769: 
        !           770:        /* clear break, keep rts dtr */
        !           771:        value = sr->wr5 & (SCC_WR5_DTR|SCC_WR5_RTS);
        !           772:        value |= SCC_WR5_TX_8_BITS;
        !           773:        sr->wr5 = value;
        !           774:        scc_write_reg(regs, sccline, SCC_WR5, value);
        !           775:        /* some are on the other channel, which might
        !           776:           never be used (e.g. maxine has only one line) */
        !           777:        {
        !           778:                register int otherline = (sccline+1)&1;
        !           779: 
        !           780:                scc_write_reg(regs, otherline, SCC_WR5, scc->softr[otherline].wr5);
        !           781:        }
        !           782: 
        !           783:        scc_write_reg(regs, sccline, SCC_WR6, 0);
        !           784:        scc_write_reg(regs, sccline, SCC_WR7, 0);
        !           785: 
        !           786:        scc_write_reg(regs, sccline, SCC_WR9, SCC_WR9_VIS);
        !           787: 
        !           788:        scc_write_reg(regs, sccline, SCC_WR10, 0);
        !           789: 
        !           790:        /* clock config */
        !           791:        value = SCC_WR11_RCLK_BAUDR | SCC_WR11_XTLK_BAUDR |
        !           792:                SCC_WR11_TRc_OUT | SCC_WR11_TRcOUT_BAUDR;
        !           793:        scc_write_reg(regs, sccline, SCC_WR11, value);
        !           794: 
        !           795:        value = scc_speeds[tp->t_ispeed];
        !           796:        scc_set_timing_base(regs,sccline,value);
        !           797: 
        !           798:        value = sr->wr14;
        !           799:        scc_write_reg(regs, sccline, SCC_WR14, value);
        !           800: 
        !           801: #if    FLAMINGO
        !           802:        if (unit != 1)
        !           803: #else
        !           804:        if (1)
        !           805: #endif
        !           806:        {
        !           807:                /* Chan-A: CTS==SI DCD==RI DSR=SYNCH */
        !           808:                value = SCC_WR15_CTS_IE | SCC_WR15_DCD_IE | SCC_WR15_SYNCHUNT_IE;
        !           809:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR15, value);
        !           810: 
        !           811:                /* Chan-B: CTS==CTS DCD==DCD */
        !           812:                value = SCC_WR15_BREAK_IE | SCC_WR15_CTS_IE | SCC_WR15_DCD_IE;
        !           813:                scc_write_reg(regs, SCC_CHANNEL_B, SCC_WR15, value);
        !           814:        } else {
        !           815:                /* Here if modem bits are floating noise, keep quiet */
        !           816:                value = SCC_WR15_BREAK_IE;
        !           817:                scc_write_reg(regs, sccline, SCC_WR15, value);
        !           818:        }
        !           819: 
        !           820:        /* and now the enables */
        !           821:        value = SCC_WR3_RX_8_BITS | SCC_WR3_RX_ENABLE;
        !           822:        scc_write_reg(regs, sccline, SCC_WR3, value);
        !           823: 
        !           824:        value = sr->wr5 | SCC_WR5_TX_ENABLE;
        !           825:        sr->wr5 = value;
        !           826:        scc_write_reg(regs, sccline, SCC_WR5, value);
        !           827: 
        !           828:        /* master inter enable */
        !           829:        scc_write_reg(regs,sccline,SCC_WR9,SCC_WR9_MASTER_IE|SCC_WR9_VIS);
        !           830: 
        !           831:        scc_write_reg(regs, sccline, SCC_WR1, sr->wr1);
        !           832: 
        !           833: }
        !           834:  
        !           835: /*
        !           836:  * Modem control functions
        !           837:  */
        !           838: scc_mctl(
        !           839:        int     dev,
        !           840:        int     bits,
        !           841:        int     how)
        !           842: {
        !           843:        register scc_regmap_t *regs;
        !           844:        struct softreg  *sra, *srb, *sr;
        !           845:        int unit, sccline;
        !           846:        int b = 0;
        !           847:        spl_t   s;
        !           848:        scc_softc_t      scc;
        !           849: 
        !           850:        /* MI code wants us to handle 4 lines on unit 0 */
        !           851:        unit = (dev < 4) ? 0 : (dev / NSCC_LINE);
        !           852:        sccline = dev;
        !           853:        mi_to_scc(&unit, &sccline);
        !           854: 
        !           855:        if ((scc = scc_softc[unit]) == 0) return 0;     /* sanity */
        !           856:        regs = scc->regs;
        !           857: 
        !           858:        sr  = &scc->softr[sccline];
        !           859:        sra = &scc->softr[SCC_CHANNEL_A];
        !           860:        srb = &scc->softr[SCC_CHANNEL_B];
        !           861: 
        !           862:        if (bits == TM_HUP) {   /* close line (internal) */
        !           863:                bits = TM_DTR | TM_RTS;
        !           864:                how = DMBIC;
        !           865:                /* xxx interrupts too ?? */
        !           866:        }
        !           867: 
        !           868:        if (bits & TM_BRK) {
        !           869:                switch (how) {
        !           870:                case DMSET:
        !           871:                case DMBIS:
        !           872:                        sr->wr5 |= SCC_WR5_SEND_BREAK;
        !           873:                        break;
        !           874:                case DMBIC:
        !           875:                        sr->wr5 &= ~SCC_WR5_SEND_BREAK;
        !           876:                        break;
        !           877:                default:
        !           878:                        goto dontbrk;
        !           879:                }
        !           880:                s = spltty();
        !           881:                scc_write_reg(regs, sccline, SCC_WR5, sr->wr5);
        !           882:                splx(s);
        !           883: dontbrk:
        !           884:                b |= (sr->wr5 & SCC_WR5_SEND_BREAK) ? TM_BRK : 0;
        !           885:        }
        !           886: 
        !           887:        /* no modem support on channel A */
        !           888:        if (sccline == SCC_CHANNEL_A)
        !           889:                return (b | TM_LE | TM_DTR | TM_CTS | TM_CAR | TM_DSR);
        !           890: 
        !           891:        sra = &scc->softr[SCC_CHANNEL_A];
        !           892:        srb = &scc->softr[SCC_CHANNEL_B];
        !           893: 
        !           894: #if 0
        !           895:        /* do I need to do something on this ? */
        !           896:        if (bits & TM_LE) {     /* line enable */
        !           897:        }
        !           898: #endif
        !           899: 
        !           900:        if (bits & (TM_DTR|TM_RTS)) {   /* data terminal ready, request to send */
        !           901:                register int    w = 0;
        !           902: 
        !           903:                if (bits & TM_DTR) w |= SCC_WR5_DTR;
        !           904:                if (bits & TM_RTS) w |= SCC_WR5_RTS;
        !           905: 
        !           906:                switch (how) {
        !           907:                case DMSET:
        !           908:                case DMBIS:
        !           909:                        sra->wr5 |= w;
        !           910:                        break;
        !           911:                case DMBIC:
        !           912:                        sra->wr5 &= ~w;
        !           913:                        break;
        !           914:                default:
        !           915:                        goto dontdtr;
        !           916:                }
        !           917:                s = spltty();
        !           918:                scc_write_reg(regs, SCC_CHANNEL_A, SCC_WR5, sra->wr5);
        !           919:                splx(s);
        !           920: dontdtr:
        !           921:                b |= (sra->wr5 & w) ? (bits & (TM_DTR|TM_RTS)) : 0;
        !           922:        }
        !           923: 
        !           924:        s = spltty();
        !           925: 
        !           926: #if 0
        !           927:        /* Unsupported */
        !           928:        if (bits & TM_ST) {     /* secondary transmit */
        !           929:        }
        !           930:        if (bits & TM_SR) {     /* secondary receive */
        !           931:        }
        !           932: #endif
        !           933: 
        !           934:        if (bits & TM_CTS) {    /* clear to send */
        !           935:                register int value;
        !           936:                scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR0, value);
        !           937:                b |= (value & SCC_RR0_CTS) ? TM_CTS : 0;
        !           938:        }
        !           939: 
        !           940:        if (bits & TM_CAR) {    /* carrier detect */
        !           941:                register int value;
        !           942:                scc_read_reg(regs, SCC_CHANNEL_B, SCC_RR0, value);
        !           943:                b |= (value & SCC_RR0_DCD) ? TM_CAR : 0;
        !           944:        }
        !           945: 
        !           946:        if (bits & TM_RNG) {    /* ring */
        !           947:                register int value;
        !           948:                scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR0, value);
        !           949:                b |= (value & SCC_RR0_DCD) ? TM_RNG : 0;
        !           950:        }
        !           951: 
        !           952:        if (bits & TM_DSR) {    /* data set ready */
        !           953:                register int value;
        !           954:                scc_read_reg(regs, SCC_CHANNEL_A, SCC_RR0, value);
        !           955:                b |= (value & SCC_RR0_SYNCH) ? TM_DSR : 0;
        !           956:        }
        !           957: 
        !           958:        splx(s);
        !           959: 
        !           960:        return b;
        !           961: }
        !           962: 
        !           963: #define debug 0
        !           964: 
        !           965: scc_modem_intr(
        !           966:        scc_softc_t      scc,
        !           967:        int             chan,
        !           968:        int             unit)
        !           969: {
        !           970:        register int value, changed;
        !           971: 
        !           972:        scc_read_reg_zero(scc->regs, chan, value);
        !           973: 
        !           974:        /* See what changed */
        !           975:        changed = value ^ scc->last_rr0[chan];
        !           976:        scc->last_rr0[chan] = value;
        !           977: 
        !           978: #if debug
        !           979: printf("sccmodem: chan %c now %x, changed %x : ",
        !           980:        (chan == SCC_CHANNEL_B) ? 'B' : 'A',
        !           981:        value, changed);
        !           982: #endif
        !           983: 
        !           984:        if (chan == SCC_CHANNEL_A) {
        !           985:                if (changed & SCC_RR0_CTS) {
        !           986:                        /* Speed indicator, ignore XXX */
        !           987: #if debug
        !           988: printf("%s-speed ", (value & SCC_RR0_CTS) ? "Full" : "Half");
        !           989: #endif
        !           990:                }
        !           991:                if (changed & SCC_RR0_DCD) {
        !           992:                        /* Ring indicator */
        !           993: #if debug
        !           994: printf("Ring ");
        !           995: #endif
        !           996:                }
        !           997:                if (changed & SCC_RR0_SYNCH) {
        !           998:                        /* Data Set Ready */
        !           999: #if debug
        !          1000: printf("DSR ");
        !          1001: #endif
        !          1002:                        /* If modem went down then CD will also go down,
        !          1003:                           or it did already.
        !          1004:                           If modem came up then we have to wait for CD
        !          1005:                           anyways before enabling the line.
        !          1006:                           Either way, nothing to do here */
        !          1007:                }
        !          1008:        } else {
        !          1009:                if (changed & SCC_RR0_CTS) {
        !          1010:                        /* Clear To Send */
        !          1011: #if debug
        !          1012: printf("CTS ");
        !          1013: #endif
        !          1014:                        tty_cts(console_tty[scc_to_mi(unit,chan)],
        !          1015:                                value & SCC_RR0_CTS);
        !          1016:                }
        !          1017:                if (changed & SCC_RR0_DCD) {
        !          1018: #if debug
        !          1019: printf("CD ");
        !          1020: #endif
        !          1021:                        check_car(console_tty[scc_to_mi(unit,chan)],
        !          1022:                                  value & SCC_RR0_DCD);
        !          1023:                }
        !          1024:        }
        !          1025: #if debug
        !          1026: printf(".\n");
        !          1027: #endif
        !          1028: }
        !          1029: 
        !          1030: private check_car(
        !          1031:        register struct tty *tp,
        !          1032:         boolean_t car)
        !          1033:                
        !          1034: {
        !          1035:        if (car) {
        !          1036: #if notyet
        !          1037:                /* cancel modem timeout if need to */
        !          1038:                if (car & (SCC_MSR_CD2 | SCC_MSR_CD3))
        !          1039:                        untimeout(scc_hup, (vm_offset_t)tp);
        !          1040: #endif
        !          1041: 
        !          1042:                /* I think this belongs in the MI code */
        !          1043:                if (tp->t_state & TS_WOPEN)
        !          1044:                        tp->t_state |= TS_ISOPEN;
        !          1045:                /* carrier present */
        !          1046:                if ((tp->t_state & TS_CARR_ON) == 0)
        !          1047:                        (void)ttymodem(tp, 1);
        !          1048:        } else if ((tp->t_state&TS_CARR_ON) && ttymodem(tp, 0) == 0)
        !          1049:                scc_mctl( tp->t_dev, TM_DTR, DMBIC);
        !          1050: }
        !          1051: 
        !          1052: /*
        !          1053:  * Periodically look at the CD signals:
        !          1054:  * they do generate interrupts but we
        !          1055:  * must fake them on channel A.  We might
        !          1056:  * also fake them on channel B.
        !          1057:  */
        !          1058: scc_scan()
        !          1059: {
        !          1060:        register i;
        !          1061:        spl_t s = spltty();
        !          1062: 
        !          1063:        for (i = 0; i < NSCC; i++) {
        !          1064:                register scc_softc_t    scc;
        !          1065:                register int            car;
        !          1066:                register struct tty     **tpp;
        !          1067: 
        !          1068:                scc = scc_softc[i];
        !          1069:                if (scc == 0)
        !          1070:                        continue;
        !          1071:                car = scc->softCAR | scc->fake;
        !          1072: 
        !          1073:                tpp = &console_tty[i * NSCC_LINE];
        !          1074: 
        !          1075:                while (car) {
        !          1076:                        if (car & 1)
        !          1077:                                check_car(*tpp, 1);
        !          1078:                        tpp++;
        !          1079:                        car  = car>>1;
        !          1080:                }
        !          1081: 
        !          1082:        }
        !          1083:        splx(s);
        !          1084:        timeout(scc_scan, (vm_offset_t)0, 5*hz);
        !          1085: }
        !          1086: 
        !          1087: 
        !          1088: #if debug
        !          1089: scc_rr0(unit,chan)
        !          1090: {
        !          1091:        int val;
        !          1092:        scc_read_reg_zero(scc_softc[unit]->regs, chan, val);
        !          1093:        return val;
        !          1094: }
        !          1095: 
        !          1096: scc_rreg(unit,chan,n)
        !          1097: {
        !          1098:        int val;
        !          1099:        scc_read_reg(scc_softc[unit]->regs, chan, n, val);
        !          1100:        return val;
        !          1101: }
        !          1102: 
        !          1103: scc_wreg(unit,chan,n,val)
        !          1104: {
        !          1105:        scc_write_reg(scc_softc[unit]->regs, chan, n, val);
        !          1106: }
        !          1107: 
        !          1108: scc_state(unit,soft)
        !          1109: {
        !          1110:        int     rr0, rr1, rr3, rr12, rr13, rr15;
        !          1111: 
        !          1112:        rr0 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR0);
        !          1113:        rr1 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR1);
        !          1114:        rr3 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR3);
        !          1115:        rr12 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR12);
        !          1116:        rr13 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR13);
        !          1117:        rr15 = scc_rreg(unit, SCC_CHANNEL_A, SCC_RR15);
        !          1118:        printf("{%d intr, A: R0 %x R1 %x R3 %x baudr %x R15 %x}\n",
        !          1119:                scc_intr_count, rr0, rr1, rr3, 
        !          1120:                (rr13 << 8) | rr12, rr15);
        !          1121: 
        !          1122:        rr0 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR0);
        !          1123:        rr1 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR1);
        !          1124:        rr3 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR2);
        !          1125:        rr12 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR12);
        !          1126:        rr13 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR13);
        !          1127:        rr15 = scc_rreg(unit, SCC_CHANNEL_B, SCC_RR15);
        !          1128:        printf("{B: R0 %x R1 %x R2 %x baudr %x R15 %x}\n",
        !          1129:                rr0, rr1, rr3, 
        !          1130:                (rr13 << 8) | rr12, rr15);
        !          1131: 
        !          1132:        if (soft) {
        !          1133:                struct softreg *sr;
        !          1134:                sr = scc_softc[unit]->softr;
        !          1135:                printf("{B: W1 %x W4 %x W5 %x W14 %x}",
        !          1136:                        sr->wr1, sr->wr4, sr->wr5, sr->wr14);
        !          1137:                sr++;
        !          1138:                printf("{A: W1 %x W4 %x W5 %x W14 %x}\n",
        !          1139:                        sr->wr1, sr->wr4, sr->wr5, sr->wr14);
        !          1140:        }
        !          1141: }
        !          1142: 
        !          1143: #endif
        !          1144: 
        !          1145: #endif NSCC > 0

unix.superglobalmegacorp.com

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