Annotation of 43BSDReno/sys/vaxstand/qdcons.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1988 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)qdcons.c    7.4 (Berkeley) 6/28/90
        !            21:  */
        !            22: 
        !            23: /*
        !            24:  *     derived from: @(#)qdcons.c  4.1 (ULTRIX    11/23/87
        !            25:  */
        !            26: 
        !            27: /************************************************************************
        !            28: *
        !            29: *      ULTRIX QDSS STANDALONE BOOT DEVICE DRIVER...
        !            30: *      device driver to boot system with QDSS as console
        !            31: *
        !            32: *************************************************************************/
        !            33: /************************************************************************
        !            34: *                                                                      *
        !            35: *                      Copyright (c) 1985 by                           *
        !            36: *              Digital Equipment Corporation, Maynard, MA              *
        !            37: *                      All rights reserved.                            *
        !            38: *                                                                      *
        !            39: *   This software is furnished under a license and may be used and     *
        !            40: *   copied  only  in accordance with the terms of such license and     *
        !            41: *   with the  inclusion  of  the  above  copyright  notice.   This     *
        !            42: *   software  or  any  other copies thereof may not be provided or     *
        !            43: *   otherwise made available to any other person.  No title to and     *
        !            44: *   ownership of the software is hereby transferred.                   *
        !            45: *                                                                      *
        !            46: *   The information in this software is subject to change  without     *
        !            47: *   notice  and should not be construed as a commitment by Digital     *
        !            48: *   Equipment Corporation.                                             *
        !            49: *                                                                      *
        !            50: *   Digital assumes no responsibility for the use  or  reliability     *
        !            51: *   of its software on equipment which is not supplied by Digital.     *
        !            52: *                                                                      *
        !            53: *************************************************************************
        !            54: * revision history: (should be moved into sccs comments)
        !            55: *************************************************************************
        !            56: *
        !            57: * 09 oct 85  longo  added uVAXII console ROM cursor reset to bottom of
        !            58: *                  the screen.  Also spruced up qdputc() & scroll_up()
        !            59: * 02 oct 85  longo  changed references to ADDRESS to be ADDRESS_COMPLETE
        !            60: * 23 aug 85  longo  changed I/O page CSR address to be 0x1F00
        !            61: * 20 aug 85  longo  created
        !            62: *
        !            63: ************************************************************************/
        !            64: 
        !            65: #include "../sys/types.h"
        !            66: #include "../vax/cpu.h"
        !            67: #define KERNEL
        !            68: #include "../vaxuba/qdioctl.h"
        !            69: #include "../vaxuba/qevent.h"
        !            70: #include "../vaxuba/qduser.h"
        !            71: #include "../vaxuba/qdreg.h"
        !            72: #undef KERNEL
        !            73: 
        !            74: /*-----------------------------------------------------------------------
        !            75: * constants used to set VAX ROM's cursor to bottom the of the screen  */
        !            76: 
        !            77: #define NVR_ADRS       0x200B8024
        !            78: 
        !            79: #define CURRENT_ROW    0x4C    /* these are offsets to the ROM's scratch.. */
        !            80: #define ROW_MIN                0x4D    /* ..RAM start adrs as picked up out of NVR */
        !            81: #define ROW_MAX                0x4E
        !            82: #define CURRENT_COL    0x50
        !            83: #define COL_MIN                0x51
        !            84: #define COL_MAX                0x52
        !            85: 
        !            86: /*----------------------------------------
        !            87: * LK201 keyboard state tracking struct */
        !            88: 
        !            89:        struct q_keyboard {
        !            90: 
        !            91:            int shift;                  /* state variables      */
        !            92:            int cntrl;
        !            93:            int lock;
        !            94:            char last;                  /* last character       */
        !            95: 
        !            96:         } q_keyboard;
        !            97: 
        !            98:        int qdputc(), qdgetc();
        !            99: 
        !           100:        extern (*v_putc)(),(*v_getc)();
        !           101: 
        !           102: /*----------------------------
        !           103: * general purpose defines  */
        !           104: 
        !           105: #define BAD    -1
        !           106: #define GOOD   0
        !           107: 
        !           108: /*----------------------------------------------
        !           109: * console cursor bitmap (block cursor type)  */
        !           110: 
        !           111:        short cons_cursor[32] = {      /* white block cursor */
        !           112: 
        !           113:  /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
        !           114:         0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
        !           115:  /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
        !           116:          0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
        !           117: 
        !           118:        };
        !           119: 
        !           120: /*-------------------------------------
        !           121: * constants used in font operations */
        !           122: 
        !           123: #define CHARS          95                      /* # of chars in the font */
        !           124: #define CHAR_HEIGHT    15                      /* char height in pixels */
        !           125: #define CHAR_WIDTH     8                       /* char width in pixels*/
        !           126: #define FONT_WIDTH     (CHAR_WIDTH * CHARS)    /* font width in pixels */
        !           127: #define ROWS           CHAR_HEIGHT
        !           128: 
        !           129: #define FONT_X         0                       /* font's off screen adrs */
        !           130: #define FONT_Y         (2047 - CHAR_HEIGHT) 
        !           131: /*
        !           132: #define FONT_Y         200
        !           133: */
        !           134: 
        !           135:        extern char q_font[];           /* reference font object code */
        !           136: 
        !           137:        extern  char q_key[];           /* reference key xlation tables */
        !           138:        extern  char q_shift_key[];
        !           139:        extern  char *q_special[];
        !           140: 
        !           141: /*----------------------------
        !           142: * console cursor structure */
        !           143: 
        !           144:        struct cons_cur {
        !           145:            int x;
        !           146:            int y;
        !           147:        } cursor;
        !           148: 
        !           149: /*------------------------------------------
        !           150: * MicroVAX-II q-bus addressing constants */
        !           151: 
        !           152: #define QMEMBASE 0x30000000
        !           153: #define QDSSCSR  0x20001F00
        !           154: 
        !           155: #define CHUNK     (64 * 1024)
        !           156: #define QMEMSIZE  (1024 * 1024 * 4)
        !           157: #define        QDBASE    (QMEMBASE + QMEMSIZE - CHUNK)
        !           158: 
        !           159: /*------------------------------------------------------------------
        !           160: * QDSS register address offsets from start of QDSS address space */
        !           161: 
        !           162: #define QDSIZE          (52 * 1024)    /* size of entire QDSS foot print */
        !           163: 
        !           164: #define TMPSIZE  (16 * 1024)   /* template RAM is 8k SHORT WORDS */
        !           165: #define TMPSTART 0x8000                /* offset of template RAM from base adrs */
        !           166: 
        !           167: #define REGSIZE         (5 * 512)      /* regs touch 2.5k (5 pages) of addr space */
        !           168: #define REGSTART 0xC000                /* offset of reg pages from base adrs */
        !           169: 
        !           170: #define ADDER  (REGSTART+0x000)
        !           171: #define DGA    (REGSTART+0x200)
        !           172: #define DUART  (REGSTART+0x400)
        !           173: #define MEMCSR  (REGSTART+0x800)
        !           174: 
        !           175: #define        CLRSIZE  (3 * 512)              /* color map size */
        !           176: #define CLRSTART (REGSTART+0xA00)      /* color map start offset from base */
        !           177:                                        /*  0x0C00 really */
        !           178: #define RED    (CLRSTART+0x000)
        !           179: #define BLUE   (CLRSTART+0x200)
        !           180: #define GREEN  (CLRSTART+0x400)
        !           181: 
        !           182: /*---------------------------------------
        !           183: * QDSS register address map structure */
        !           184: 
        !           185:        struct qdmap qdmap;
        !           186: 
        !           187: /************************************************************************
        !           188: *************************************************************************
        !           189: *************************************************************************
        !           190: *
        !           191: *      EXTERNALLY CALLED ROUTINES START HERE:
        !           192: *
        !           193: *************************************************************************
        !           194: *************************************************************************
        !           195: ************************************************************************/
        !           196: 
        !           197: /************************************************************************
        !           198: *
        !           199: *      qd_init()... init the QDSS into a physical memory system
        !           200: *
        !           201: ************************************************************************/
        !           202: 
        !           203: qd_init()
        !           204: {
        !           205:        register char *ROM_console;
        !           206:        register short *NVR;
        !           207:        register int i;
        !           208: 
        !           209:        caddr_t qdaddr;
        !           210:        struct dga *dga;
        !           211:        extern int cpu;
        !           212: 
        !           213:        qdaddr = (caddr_t) QDSSCSR;
        !           214:         if (badaddr(qdaddr, sizeof(short)))
        !           215:             return(0);
        !           216: 
        !           217:        *(short *)qdaddr = (short) (QDBASE >> 16);
        !           218: 
        !           219: /*----------------------------------------------------------------------
        !           220: * load qdmap struct with the physical addresses of the QDSS elements */
        !           221: 
        !           222:        qdmap.template = (caddr_t) QDBASE + TMPSTART;
        !           223:        qdmap.adder = (caddr_t) QDBASE + ADDER;
        !           224:        qdmap.dga = (caddr_t) QDBASE + DGA;
        !           225:        qdmap.duart = (caddr_t) QDBASE + DUART;
        !           226:        qdmap.memcsr = (caddr_t) QDBASE + MEMCSR;
        !           227:        qdmap.red = (caddr_t) QDBASE + RED;
        !           228:        qdmap.blue = (caddr_t) QDBASE + BLUE;
        !           229:        qdmap.green = (caddr_t) QDBASE + GREEN;
        !           230: 
        !           231: /*--------------------------
        !           232: * no interrupts allowed! */
        !           233: 
        !           234:        dga = (struct dga *) qdmap.dga;
        !           235:        dga->csr = HALT;
        !           236:        dga->csr |= CURS_ENB;
        !           237: 
        !           238: /*----------------------------
        !           239: * init the default values  */
        !           240: 
        !           241:        q_keyboard.shift = 0;           /* init keyboard state tracking */
        !           242:        q_keyboard.lock = 0;
        !           243:        q_keyboard.cntrl = 0;
        !           244:        q_keyboard.last = 0;
        !           245: 
        !           246:        cursor.x = 0;                   /* init cursor to top left */
        !           247:        cursor.y = 0;
        !           248: 
        !           249:        set_defaults();                 /* setup the default device */
        !           250:        ldfont();                       /* PtoB the font into off-screen */
        !           251: 
        !           252: /*--------------------------------------------------------------------
        !           253: * tell the VAX ROM that the cursor is at the bottom of the screen  */
        !           254: 
        !           255:        if (cpu == VAX_630) {
        !           256:                NVR = (short *) NVR_ADRS;
        !           257: 
        !           258:                i = *NVR++ & 0xFF;
        !           259:                i |= (*NVR++ & 0xFF) << 8;
        !           260:                i |= (*NVR++ & 0xFF) << 16;
        !           261:                i |= (*NVR++ & 0xFF) << 24;
        !           262: 
        !           263:                ROM_console = (char *) i;
        !           264: 
        !           265:                ROM_console[CURRENT_COL] = ROM_console[COL_MIN];
        !           266:                ROM_console[CURRENT_ROW] = ROM_console[ROW_MAX];
        !           267:        }
        !           268: 
        !           269: /*----------------------------------------------------------
        !           270: * smash system virtual console service routine addresses */
        !           271: 
        !           272:        printf("switching console to QDSS display...\n");
        !           273:        v_getc = qdgetc;
        !           274:        v_putc = qdputc;
        !           275: 
        !           276:        return(1);
        !           277: 
        !           278: } /* qd_init */
        !           279: 
        !           280: /******************************************************************* 
        !           281: *
        !           282: *      qdputc()... output a character to the QDSS screen
        !           283: *
        !           284: ********************************************************************
        !           285: *
        !           286: *      calling convention:
        !           287: *
        !           288: *              qdputc(chr);
        !           289: *              char chr;               ;character to be displayed
        !           290: *
        !           291: ********/
        !           292: 
        !           293: qdputc(chr)
        !           294: char chr;
        !           295: {
        !           296:        register struct adder *adder;
        !           297:        register struct dga *dga;
        !           298:        register int i;
        !           299: 
        !           300:        short x;
        !           301: 
        !           302:        adder = (struct adder *) qdmap.adder;
        !           303:        dga = (struct dga *) qdmap.dga;
        !           304: 
        !           305: /*---------------------------
        !           306: * non display character?  */
        !           307: 
        !           308:        chr &= 0x7F;
        !           309: 
        !           310:        switch (chr) {
        !           311: 
        !           312:            case '\r':                  /* return char */
        !           313:                cursor.x = 0;
        !           314:                dga->x_cursor = TRANX(cursor.x);
        !           315:                return(0);
        !           316: 
        !           317:            case '\t':                  /* tab char */
        !           318: 
        !           319:                for (i = 8 - ((cursor.x >> 3) & 0x07); i > 0; --i) {
        !           320:                    qdputc(' ');
        !           321:                }
        !           322:                return(0);
        !           323: 
        !           324:            case '\n':                  /* line feed char */
        !           325: 
        !           326:                if ((cursor.y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) {
        !           327:                    cursor.y -= CHAR_HEIGHT;
        !           328:                    scroll_up(adder);
        !           329:                }
        !           330:                dga->y_cursor = TRANY(cursor.y);
        !           331:                return(0);
        !           332: 
        !           333:            case '\b':                  /* backspace char */
        !           334:                if (cursor.x > 0) {
        !           335:                    cursor.x -= CHAR_WIDTH;
        !           336:                    qdputc(' ');
        !           337:                    cursor.x -= CHAR_WIDTH;
        !           338:                    dga->x_cursor = TRANX(cursor.x);
        !           339:                }
        !           340:                return(0);
        !           341: 
        !           342:            default:
        !           343:                if (chr < ' ' || chr > '~') {
        !           344:                    return(0);
        !           345:                }
        !           346:        }
        !           347: 
        !           348: /*------------------------------------------
        !           349: * setup VIPER operand control registers  */
        !           350: 
        !           351:        write_ID(adder, CS_UPDATE_MASK, 0x0001);  /* select plane #0 */
        !           352:        write_ID(adder, SRC1_OCR_B, 
        !           353:                        EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
        !           354: 
        !           355:        write_ID(adder, CS_UPDATE_MASK, 0x00FE);  /* select other planes */
        !           356:        write_ID(adder, SRC1_OCR_B, 
        !           357:                        EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY);
        !           358: 
        !           359:        write_ID(adder, CS_UPDATE_MASK, 0x00FF);  /* select all planes */
        !           360:        write_ID(adder, DST_OCR_B, 
        !           361:                        EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
        !           362: 
        !           363:        write_ID(adder, MASK_1, 0xFFFF);
        !           364:        write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1);
        !           365:        write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
        !           366: 
        !           367: /*----------------------------------------
        !           368: * load DESTINATION origin and vectors  */
        !           369: 
        !           370:        adder->fast_dest_dy = 0;
        !           371:        adder->slow_dest_dx = 0;
        !           372:        adder->error_1 = 0;
        !           373:        adder->error_2 = 0;
        !           374: 
        !           375:        adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
        !           376: 
        !           377:        wait_status(adder, RASTEROP_COMPLETE);
        !           378: 
        !           379:        adder->destination_x = cursor.x;
        !           380:        adder->fast_dest_dx = CHAR_WIDTH;
        !           381: 
        !           382:        adder->destination_y = cursor.y;
        !           383:        adder->slow_dest_dy = CHAR_HEIGHT;
        !           384: 
        !           385: /*-----------------------------------
        !           386: * load SOURCE origin and vectors  */
        !           387: 
        !           388:        adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH);
        !           389:        adder->source_1_y = FONT_Y;
        !           390: 
        !           391:        adder->source_1_dx = CHAR_WIDTH;
        !           392:        adder->source_1_dy = CHAR_HEIGHT;
        !           393: 
        !           394:        write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
        !           395:        adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
        !           396: 
        !           397: /*-------------------------------------
        !           398: * update console cursor coordinates */
        !           399: 
        !           400:        cursor.x += CHAR_WIDTH;
        !           401:        dga->x_cursor = TRANX(cursor.x);
        !           402: 
        !           403:         if (cursor.x > (1024 - CHAR_WIDTH)) {
        !           404:            qdputc('\r');
        !           405:            qdputc('\n');
        !           406:        }
        !           407: 
        !           408: } /* qdputc */ 
        !           409: 
        !           410: /******************************************************************* 
        !           411: *
        !           412: *      qdgetc()... get a character from the LK201
        !           413: *
        !           414: *******************************************************************/
        !           415: 
        !           416: qdgetc()
        !           417: {
        !           418:        register short key;
        !           419:        register char chr;
        !           420:        register struct duart *duart;
        !           421: 
        !           422:        u_int status;
        !           423: 
        !           424:        duart = (struct duart *) qdmap.duart;
        !           425: 
        !           426:        /*--------------------------------------
        !           427:        * Get a character from the keyboard. */
        !           428: 
        !           429: LOOP:
        !           430:        while (!((status = duart->statusA) & RCV_RDY))
        !           431:                        ;
        !           432: 
        !           433:        key = duart->dataA;
        !           434:        key &= 0xFF;
        !           435: 
        !           436:        /*--------------------------------------
        !           437:        * Check for various keyboard errors  */
        !           438: 
        !           439:        if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR ||
        !           440:            key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) {
        !           441:                printf("Keyboard error, code = %x\n", key);
        !           442:                return(0);
        !           443:        }
        !           444: 
        !           445:        if (key < LK_LOWEST) 
        !           446:            return(0);
        !           447: 
        !           448:        /*---------------------------------
        !           449:        * See if its a state change key */
        !           450: 
        !           451:        switch (key) {
        !           452: 
        !           453:            case LOCK:
        !           454:                q_keyboard.lock ^= 0xffff;      /* toggle */
        !           455:                if (q_keyboard.lock)
        !           456:                    led_control(LK_LED_ENABLE, LK_LED_LOCK);
        !           457:                else
        !           458:                    led_control(LK_LED_DISABLE, LK_LED_LOCK);
        !           459:                goto LOOP;
        !           460: 
        !           461:            case SHIFT:
        !           462:                q_keyboard.shift ^= 0xFFFF;
        !           463:                goto LOOP;
        !           464: 
        !           465:            case CNTRL:
        !           466:                q_keyboard.cntrl ^= 0xFFFF;
        !           467:                goto LOOP;
        !           468: 
        !           469:            case ALLUP:
        !           470:                q_keyboard.cntrl = 0;
        !           471:                q_keyboard.shift = 0;
        !           472:                goto LOOP;
        !           473: 
        !           474:            case REPEAT:
        !           475:                chr = q_keyboard.last;
        !           476:                break;
        !           477: 
        !           478:            /*-------------------------------------------------------
        !           479:            * Test for cntrl characters. If set, see if the character
        !           480:            * is elligible to become a control character. */
        !           481: 
        !           482:            default:
        !           483: 
        !           484:                if (q_keyboard.cntrl) {
        !           485:                    chr = q_key[key];
        !           486:                    if (chr >= ' ' && chr <= '~')
        !           487:                        chr &= 0x1F;
        !           488:                } 
        !           489:                else if ( q_keyboard.lock || q_keyboard.shift )
        !           490:                    chr = q_shift_key[key];
        !           491:                else
        !           492:                    chr = q_key[key];
        !           493:                break;  
        !           494:        }
        !           495: 
        !           496:        if (chr < ' ' && chr > '~')     /* if input is non-displayable */
        !           497:            return(0);                  /* ..then pitch it! */
        !           498: 
        !           499:        q_keyboard.last = chr;
        !           500: 
        !           501:        /*-----------------------------------
        !           502:        * Check for special function keys */
        !           503: 
        !           504:        if (chr & 0x80)                 /* pitch the function keys */
        !           505:            return(0);
        !           506:        else
        !           507:            return(chr);
        !           508: 
        !           509: } /* qdgetc */
        !           510: 
        !           511: /************************************************************************
        !           512: *************************************************************************
        !           513: *************************************************************************
        !           514: *
        !           515: *      INTERNALLY USED ROUTINES START HERE:
        !           516: *
        !           517: *************************************************************************
        !           518: *************************************************************************
        !           519: ************************************************************************/
        !           520: 
        !           521: /********************************************************************
        !           522: *
        !           523: *      ldcursor()... load the mouse cursor's template RAM bitmap
        !           524: *
        !           525: ********************************************************************/
        !           526: 
        !           527: ldcursor()
        !           528: {
        !           529:        register struct dga *dga;
        !           530:        register short *temp;
        !           531:        register int i;
        !           532: 
        !           533:        int cursor;
        !           534: 
        !           535:        dga = (struct dga *) qdmap.dga;
        !           536:        temp = (short *) qdmap.template;
        !           537: 
        !           538:        temp += (8 * 1024) - 32;        /* cursor is 32 WORDS from the end */
        !           539:                                        /* ..of the 8k WORD template space */
        !           540:        for (i = 0; i < 32; ++i)
        !           541:            *temp++ = cons_cursor[i];
        !           542: 
        !           543:        return(0);
        !           544: 
        !           545: } /* ldcursor */
        !           546: 
        !           547: /**********************************************************************
        !           548: *
        !           549: *      ldfont()... put the console font in the QDSS off-screen memory
        !           550: *
        !           551: **********************************************************************/
        !           552: 
        !           553: ldfont()
        !           554: {
        !           555:        register struct adder *adder;
        !           556: 
        !           557:        int i;          /* scratch variables */
        !           558:        int j;
        !           559:        int k;
        !           560:        short packed;
        !           561: 
        !           562:        adder = (struct adder *) qdmap.adder;
        !           563: 
        !           564: /*------------------------------------------
        !           565: * setup VIPER operand control registers  */
        !           566: 
        !           567:        write_ID(adder, MASK_1, 0xFFFF);
        !           568:        write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
        !           569:        write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
        !           570: 
        !           571:        write_ID(adder, SRC1_OCR_B, 
        !           572:                        EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
        !           573:        write_ID(adder, SRC2_OCR_B, 
        !           574:                        EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
        !           575:        write_ID(adder, DST_OCR_B, 
        !           576:                        EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
        !           577: 
        !           578:        adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
        !           579: 
        !           580: /*--------------------------
        !           581: * load destination data  */
        !           582: 
        !           583:        wait_status(adder, RASTEROP_COMPLETE);
        !           584: 
        !           585:        adder->destination_x = FONT_X;
        !           586:        adder->destination_y = FONT_Y;
        !           587:        adder->fast_dest_dx = FONT_WIDTH;
        !           588:        adder->slow_dest_dy = CHAR_HEIGHT;
        !           589: 
        !           590: /*---------------------------------------
        !           591: * setup for processor to bitmap xfer  */
        !           592: 
        !           593:        write_ID(adder, CS_UPDATE_MASK, 0x0001);
        !           594:        adder->cmd = PBT | OCRB | 2 | DTE | 2;
        !           595: 
        !           596: /*-----------------------------------------------
        !           597: * iteratively do the processor to bitmap xfer */
        !           598: 
        !           599:        for (i = 0; i < ROWS; ++i) {
        !           600: 
        !           601:            /* PTOB a scan line */
        !           602: 
        !           603:            for (j = 0, k = i; j < 48; ++j) { 
        !           604: 
        !           605:                /* PTOB one scan of a char cell */
        !           606: 
        !           607:                packed = q_font[k];
        !           608:                k += ROWS;
        !           609:                packed |= ((short)q_font[k] << 8);
        !           610:                k += ROWS;
        !           611: 
        !           612:                wait_status(adder, TX_READY);
        !           613:                adder->id_data = packed;
        !           614:            }
        !           615:        }
        !           616: 
        !           617: }  /* ldfont */
        !           618: 
        !           619: /*********************************************************************
        !           620: *
        !           621: *      led_control()... twiddle LK-201 LED's
        !           622: *
        !           623: **********************************************************************
        !           624: *
        !           625: *      led_control(cmd, led_mask);
        !           626: *      int cmd;        LED enable/disable command
        !           627: *      int led_mask;   which LED(s) to twiddle
        !           628: *
        !           629: *************/
        !           630: 
        !           631: led_control(cmd, led_mask)
        !           632: int cmd;
        !           633: int led_mask;
        !           634: {
        !           635:        register int i;
        !           636:        register int status;
        !           637:        register struct duart *duart;
        !           638: 
        !           639:        duart = (struct duart *) qdmap.duart;
        !           640: 
        !           641:        for (i = 1000; i > 0; --i) {
        !           642:            if ((status = duart->statusA) & XMT_RDY) {
        !           643:                duart->dataA = cmd;
        !           644:                break;
        !           645:            }
        !           646:        }
        !           647: 
        !           648:        for (i = 1000; i > 0; --i) {
        !           649:            if ((status = duart->statusA) & XMT_RDY) {
        !           650:                duart->dataA = led_mask;
        !           651:                break;
        !           652:            }
        !           653:        }
        !           654: 
        !           655:        if (i == 0)
        !           656:            return(BAD);
        !           657: 
        !           658:        return(GOOD);
        !           659: 
        !           660: } /* led_control */
        !           661: 
        !           662: /******************************************************************* 
        !           663: *
        !           664: *      scroll_up()... move the screen up one character height
        !           665: *
        !           666: ********************************************************************
        !           667: *
        !           668: *      calling convention:
        !           669: *
        !           670: *              scroll_up(adder);
        !           671: *              struct adder *adder;    ;address of adder
        !           672: *
        !           673: ********/
        !           674: 
        !           675: scroll_up(adder)
        !           676: register struct adder *adder;
        !           677: {
        !           678: 
        !           679: /*------------------------------------------
        !           680: * setup VIPER operand control registers  */
        !           681: 
        !           682:        wait_status(adder, ADDRESS_COMPLETE);
        !           683: 
        !           684:        write_ID(adder, CS_UPDATE_MASK, 0x00FF);  /* select all planes */
        !           685: 
        !           686:        write_ID(adder, MASK_1, 0xFFFF);
        !           687:        write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
        !           688:        write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
        !           689: 
        !           690:        write_ID(adder, SRC1_OCR_B, 
        !           691:                        EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
        !           692:        write_ID(adder, DST_OCR_B, 
        !           693:                        EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
        !           694: 
        !           695: /*----------------------------------------
        !           696: * load DESTINATION origin and vectors  */
        !           697: 
        !           698:        adder->fast_dest_dy = 0;
        !           699:        adder->slow_dest_dx = 0;
        !           700:        adder->error_1 = 0;
        !           701:        adder->error_2 = 0;
        !           702: 
        !           703:        adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
        !           704: 
        !           705:        adder->destination_x = 0;
        !           706:        adder->fast_dest_dx = 1024;
        !           707: 
        !           708:        adder->destination_y = 0;
        !           709:        adder->slow_dest_dy = 864 - CHAR_HEIGHT;
        !           710: 
        !           711: /*-----------------------------------
        !           712: * load SOURCE origin and vectors  */
        !           713: 
        !           714:        adder->source_1_x = 0;
        !           715:        adder->source_1_dx = 1024;
        !           716: 
        !           717:        adder->source_1_y = 0 + CHAR_HEIGHT;
        !           718:        adder->source_1_dy = 864 - CHAR_HEIGHT;
        !           719: 
        !           720:        write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
        !           721:        adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
        !           722: 
        !           723: /*--------------------------------------------
        !           724: * do a rectangle clear of last screen line */
        !           725: 
        !           726:        write_ID(adder, MASK_1, 0xffff);
        !           727:        write_ID(adder, SOURCE, 0xffff);
        !           728:        write_ID(adder,DST_OCR_B,  
        !           729:                (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY));
        !           730:        write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0);
        !           731:        adder->error_1 = 0;
        !           732:        adder->error_2 = 0;
        !           733:        adder->slow_dest_dx = 0;        /* set up the width of  */
        !           734:        adder->slow_dest_dy = CHAR_HEIGHT;      /* rectangle */
        !           735: 
        !           736:        adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ;
        !           737:        wait_status(adder, RASTEROP_COMPLETE);
        !           738:        adder->destination_x = 0;
        !           739:        adder->destination_y = 864 - CHAR_HEIGHT;
        !           740: 
        !           741:        adder->fast_dest_dx = 1024;     /* set up the height    */
        !           742:        adder->fast_dest_dy = 0;        /* of rectangle         */
        !           743: 
        !           744:        write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE));
        !           745:        adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ;
        !           746: 
        !           747: } /* scroll_up */ 
        !           748: 
        !           749: /**********************************************************************
        !           750: *
        !           751: *      set_defaults()... init the QDSS device and driver defaults
        !           752: *
        !           753: **********************************************************************/
        !           754: 
        !           755: set_defaults()
        !           756: {
        !           757:        setup_input();          /* init the DUART */
        !           758:        setup_dragon();         /* init the ADDER/VIPER stuff */
        !           759:        ldcursor();             /* load default cursor map */
        !           760: 
        !           761: } /* set_defaults */
        !           762: 
        !           763: /*********************************************************************
        !           764: *
        !           765: *      setup_dragon()... init the ADDER, VIPER, bitmaps, & color map
        !           766: *
        !           767: *********************************************************************/
        !           768: 
        !           769: setup_dragon()
        !           770: {
        !           771: 
        !           772:        register struct adder *adder;
        !           773:        register struct dga *dga;
        !           774:        short *memcsr;
        !           775: 
        !           776:        int i;                  /* general purpose variables */
        !           777:        int status;
        !           778: 
        !           779:        short top;              /* clipping/scrolling boundaries */
        !           780:        short bottom;
        !           781:        short right;
        !           782:        short left;
        !           783: 
        !           784:        short *red;             /* color map pointers */
        !           785:        short *green;
        !           786:        short *blue;
        !           787: 
        !           788: /*------------------
        !           789: * init for setup */
        !           790: 
        !           791:        adder = (struct adder *) qdmap.adder;
        !           792:        dga = (struct dga *) qdmap.dga;
        !           793:        memcsr = (short *) qdmap.memcsr;
        !           794:        
        !           795:        *memcsr = SYNC_ON;              /* blank screen and turn off LED's */
        !           796:        adder->command = CANCEL;
        !           797: 
        !           798: /*----------------------
        !           799: * set monitor timing */
        !           800: 
        !           801:        adder->x_scan_count_0 = 0x2800;
        !           802:        adder->x_scan_count_1 = 0x1020;
        !           803:        adder->x_scan_count_2 = 0x003A;
        !           804:        adder->x_scan_count_3 = 0x38F0;
        !           805:        adder->x_scan_count_4 = 0x6128;
        !           806:        adder->x_scan_count_5 = 0x093A;
        !           807:        adder->x_scan_count_6 = 0x313C;
        !           808:        adder->sync_phase_adj = 0x0100;
        !           809:        adder->x_scan_conf = 0x00C8;
        !           810: 
        !           811: /*---------------------------------------------------------
        !           812: * got a bug in secound pass ADDER! lets take care of it */
        !           813: 
        !           814:        /* normally, just use the code in the following bug fix code, but to 
        !           815:        * make repeated demos look pretty, load the registers as if there was
        !           816:        * no bug and then test to see if we are getting sync */
        !           817: 
        !           818:        adder->y_scan_count_0 = 0x135F;
        !           819:        adder->y_scan_count_1 = 0x3363;
        !           820:        adder->y_scan_count_2 = 0x2366;
        !           821:        adder->y_scan_count_3 = 0x0388;
        !           822: 
        !           823:        /* if no sync, do the bug fix code */
        !           824: 
        !           825:        if (wait_status(adder, VSYNC) == BAD) {
        !           826: 
        !           827:            /* first load all Y scan registers with very short frame and
        !           828:            * wait for scroll service.  This guarantees at least one SYNC 
        !           829:            * to fix the pass 2 Adder initialization bug (synchronizes
        !           830:            * XCINCH with DMSEEDH) */
        !           831: 
        !           832:            adder->y_scan_count_0 = 0x01;
        !           833:            adder->y_scan_count_1 = 0x01;
        !           834:            adder->y_scan_count_2 = 0x01;
        !           835:            adder->y_scan_count_3 = 0x01;
        !           836: 
        !           837:            wait_status(adder, VSYNC);  /* delay at least 1 full frame time */
        !           838:            wait_status(adder, VSYNC);
        !           839: 
        !           840:            /* now load the REAL sync values (in reverse order just to
        !           841:            *  be safe.  */
        !           842: 
        !           843:            adder->y_scan_count_3 = 0x0388;
        !           844:            adder->y_scan_count_2 = 0x2366;
        !           845:            adder->y_scan_count_1 = 0x3363;
        !           846:            adder->y_scan_count_0 = 0x135F;
        !           847:        }
        !           848: 
        !           849: /*----------------------------
        !           850: * zero the index registers */
        !           851: 
        !           852:        adder->x_index_pending = 0;
        !           853:        adder->y_index_pending = 0;
        !           854:        adder->x_index_new = 0;
        !           855:        adder->y_index_new = 0;
        !           856:        adder->x_index_old = 0;
        !           857:        adder->y_index_old = 0;
        !           858: 
        !           859:        adder->pause = 0;
        !           860: 
        !           861: /*----------------------------------------
        !           862: * set rasterop mode to normal pen down */
        !           863: 
        !           864:        adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
        !           865: 
        !           866: /*--------------------------------------------------
        !           867: * set the rasterop registers to a default values */
        !           868: 
        !           869:        adder->source_1_dx = 1;
        !           870:        adder->source_1_dy = 1;
        !           871:        adder->source_1_x = 0;
        !           872:        adder->source_1_y = 0;
        !           873:        adder->destination_x = 0;
        !           874:        adder->destination_y = 0;
        !           875:        adder->fast_dest_dx = 1;
        !           876:        adder->fast_dest_dy = 0;
        !           877:        adder->slow_dest_dx = 0;
        !           878:        adder->slow_dest_dy = 1;
        !           879:        adder->error_1 = 0;
        !           880:        adder->error_2 = 0;
        !           881: 
        !           882: /*------------------------
        !           883: * scale factor = unity */
        !           884: 
        !           885:        adder->fast_scale = UNITY;
        !           886:        adder->slow_scale = UNITY;
        !           887: 
        !           888: /*-------------------------------
        !           889: * set the source 2 parameters */
        !           890: 
        !           891:        adder->source_2_x = 0;
        !           892:        adder->source_2_y = 0;
        !           893:        adder->source_2_size = 0x0022;
        !           894: 
        !           895: /*-----------------------------------------------
        !           896: * initialize plane addresses for eight vipers */
        !           897: 
        !           898:        write_ID(adder, CS_UPDATE_MASK, 0x0001);
        !           899:        write_ID(adder, PLANE_ADDRESS, 0x0000);
        !           900: 
        !           901:        write_ID(adder, CS_UPDATE_MASK, 0x0002);
        !           902:        write_ID(adder, PLANE_ADDRESS, 0x0001);
        !           903: 
        !           904:        write_ID(adder, CS_UPDATE_MASK, 0x0004);
        !           905:        write_ID(adder, PLANE_ADDRESS, 0x0002);
        !           906: 
        !           907:        write_ID(adder, CS_UPDATE_MASK, 0x0008);
        !           908:        write_ID(adder, PLANE_ADDRESS, 0x0003);
        !           909: 
        !           910:        write_ID(adder, CS_UPDATE_MASK, 0x0010);
        !           911:        write_ID(adder, PLANE_ADDRESS, 0x0004);
        !           912: 
        !           913:        write_ID(adder, CS_UPDATE_MASK, 0x0020);
        !           914:        write_ID(adder, PLANE_ADDRESS, 0x0005);
        !           915: 
        !           916:        write_ID(adder, CS_UPDATE_MASK, 0x0040);
        !           917:        write_ID(adder, PLANE_ADDRESS, 0x0006);
        !           918: 
        !           919:        write_ID(adder, CS_UPDATE_MASK, 0x0080);
        !           920:        write_ID(adder, PLANE_ADDRESS, 0x0007);
        !           921: 
        !           922:        /* initialize the external registers. */
        !           923: 
        !           924:        write_ID(adder, CS_UPDATE_MASK, 0x00FF);
        !           925:        write_ID(adder, CS_SCROLL_MASK, 0x00FF);
        !           926: 
        !           927:        /* initialize resolution mode */
        !           928: 
        !           929:        write_ID(adder, MEMORY_BUS_WIDTH, 0x000C);     /* bus width = 16 */
        !           930:        write_ID(adder, RESOLUTION_MODE, 0x0000);      /* one bit/pixel */
        !           931: 
        !           932:        /* initialize viper registers */
        !           933: 
        !           934:        write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP);
        !           935:        write_ID(adder, SCROLL_FILL, 0x0000);
        !           936: 
        !           937: /*----------------------------------------------------
        !           938: * set clipping and scrolling limits to full screen */
        !           939: 
        !           940:        for ( i = 1000, adder->status = 0
        !           941:            ; i > 0  &&  !((status = adder->status) & ADDRESS_COMPLETE)
        !           942:            ; --i);
        !           943: 
        !           944:        if (i == 0)
        !           945:            printf("timeout trying to setup clipping\n");
        !           946: 
        !           947:        top = 0;
        !           948:        bottom = 2048;
        !           949:        left = 0;
        !           950:        right = 1024;
        !           951: 
        !           952:        adder->x_clip_min = left;
        !           953:        adder->x_clip_max = right;
        !           954:        adder->y_clip_min = top;
        !           955:        adder->y_clip_max = bottom;
        !           956: 
        !           957:        adder->scroll_x_min = left;
        !           958:        adder->scroll_x_max = right;
        !           959:        adder->scroll_y_min = top;
        !           960:        adder->scroll_y_max = bottom;
        !           961: 
        !           962:        wait_status(adder, VSYNC);      /* wait at LEAST 1 full frame */
        !           963:        wait_status(adder, VSYNC);
        !           964: 
        !           965:        adder->x_index_pending = left;
        !           966:        adder->y_index_pending = top;
        !           967:        adder->x_index_new = left;
        !           968:        adder->y_index_new = top;
        !           969:        adder->x_index_old = left;
        !           970:        adder->y_index_old = top;
        !           971: 
        !           972:        for ( i = 1000, adder->status = 0
        !           973:            ; i > 0  &&  !((status = adder->status) & ADDRESS_COMPLETE)
        !           974:            ; --i);
        !           975: 
        !           976:        if (i == 0)
        !           977:            printf("timeout waiting for ADDRESS_COMPLETE bit\n");
        !           978: 
        !           979:        write_ID(adder, LEFT_SCROLL_MASK, 0x0000);
        !           980:        write_ID(adder, RIGHT_SCROLL_MASK, 0x0000);
        !           981: 
        !           982: /*------------------------------------------------------------
        !           983: * set source and the mask register to all ones (ie: white) */
        !           984: 
        !           985:        write_ID(adder, SOURCE, 0xFFFF);
        !           986:        write_ID(adder, MASK_1, 0xFFFF);
        !           987:        write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
        !           988:        write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
        !           989: 
        !           990: /*--------------------------------------------------------------
        !           991: * initialize Operand Control Register banks for fill command */
        !           992: 
        !           993:        write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2  | NO_ID | WAIT);
        !           994:        write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT);
        !           995:        write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE   | NO_ID | NO_WAIT);
        !           996: 
        !           997:        write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT);
        !           998:        write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2  | NO_ID | NO_WAIT);
        !           999:        write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT);
        !          1000: 
        !          1001: /*------------------------------------------------------------------
        !          1002: * init Logic Unit Function registers, (these are just common values,
        !          1003: * and may be changed as required).  */
        !          1004: 
        !          1005:        write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
        !          1006:        write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2);
        !          1007:        write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S);
        !          1008:        write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S);
        !          1009: 
        !          1010: /*----------------------------------------
        !          1011: * load the color map for black & white */
        !          1012:        
        !          1013:        for ( i = 0, adder->status = 0
        !          1014:            ; i < 10000  &&  !((status = adder->status) & VSYNC)
        !          1015:            ; ++i);
        !          1016: 
        !          1017:        if (i == 0)
        !          1018:            printf("timeout waiting for VSYNC bit\n");
        !          1019: 
        !          1020:        red = (short *) qdmap.red;
        !          1021:        green = (short *) qdmap.green;
        !          1022:        blue = (short *) qdmap.blue;
        !          1023: 
        !          1024:        *red++ = 0x00;                  /* black */
        !          1025:        *green++ = 0x00;
        !          1026:        *blue++ = 0x00;
        !          1027: 
        !          1028:        *red-- = 0xFF;                  /* white */
        !          1029:        *green-- = 0xFF;
        !          1030:        *blue-- = 0xFF;
        !          1031: 
        !          1032:        /*----------------------------------
        !          1033:        * set color map for mouse cursor */
        !          1034: 
        !          1035:        red += 254;
        !          1036:        green += 254;
        !          1037:        blue += 254;
        !          1038: 
        !          1039:        *red++ = 0x00;                  /* black */
        !          1040:        *green++ = 0x00;
        !          1041:        *blue++ = 0x00;
        !          1042: 
        !          1043:        *red = 0xFF;                    /* white */
        !          1044:        *green = 0xFF;
        !          1045:        *blue = 0xFF;
        !          1046: 
        !          1047: /*---------------------------------------------------------------------------
        !          1048: * clear the bitmap a piece at a time.  Since the fast scroll clear only clears
        !          1049: * the current displayed portion of the bitmap put a temporary value in the y
        !          1050: * limit register so we can access whole bitmap  */
        !          1051: 
        !          1052:        adder->x_limit = 1024;
        !          1053:        adder->y_limit = 2048 - CHAR_HEIGHT;
        !          1054:        adder->y_offset_pending = 0;
        !          1055: 
        !          1056:        wait_status(adder, VSYNC);      /* wait at LEAST 1 full frame */
        !          1057:        wait_status(adder, VSYNC);
        !          1058: 
        !          1059:        adder->y_scroll_constant = SCROLL_ERASE;
        !          1060: 
        !          1061:        wait_status(adder, VSYNC);
        !          1062:        wait_status(adder, VSYNC);
        !          1063: 
        !          1064:        adder->y_offset_pending = 864;
        !          1065: 
        !          1066:        wait_status(adder, VSYNC);
        !          1067:        wait_status(adder, VSYNC);
        !          1068: 
        !          1069:        adder->y_scroll_constant = SCROLL_ERASE;
        !          1070: 
        !          1071:        wait_status(adder, VSYNC);
        !          1072:        wait_status(adder, VSYNC);
        !          1073: 
        !          1074:        adder->y_offset_pending = 1728;
        !          1075: 
        !          1076:        wait_status(adder, VSYNC);
        !          1077:        wait_status(adder, VSYNC);
        !          1078: 
        !          1079:        adder->y_scroll_constant = SCROLL_ERASE;
        !          1080: 
        !          1081:        wait_status(adder, VSYNC);
        !          1082:        wait_status(adder, VSYNC);
        !          1083: 
        !          1084:        adder->y_offset_pending = 0;     /* back to normal */
        !          1085: 
        !          1086:        wait_status(adder, VSYNC);
        !          1087:        wait_status(adder, VSYNC);
        !          1088: 
        !          1089:        adder->x_limit = MAX_SCREEN_X;
        !          1090:        adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT;
        !          1091: 
        !          1092:        *memcsr = SYNC_ON | UNBLANK;    /* turn off leds and turn on video */
        !          1093:        return(0);
        !          1094: 
        !          1095: } /* setup_dragon */
        !          1096: 
        !          1097: /******************************************************************
        !          1098: *
        !          1099: *      setup_input()... init the DUART and set defaults in input
        !          1100: *                       devices
        !          1101: *
        !          1102: ******************************************************************/
        !          1103: 
        !          1104: setup_input()
        !          1105: {
        !          1106:        register struct duart *duart;   /* DUART register structure pointer */
        !          1107:        register int bits;
        !          1108:        int i, j;                       /* scratch variables */
        !          1109: 
        !          1110:        short status;
        !          1111: 
        !          1112: /*---------------
        !          1113: * init stuff */
        !          1114: 
        !          1115:        duart = (struct duart *) qdmap.duart;
        !          1116: 
        !          1117: /*---------------------------------------------
        !          1118: * setup the DUART for kbd & pointing device */
        !          1119: 
        !          1120:        duart->cmdA = RESET_M;    /* reset mode reg ptr for kbd */
        !          1121:        duart->modeA = 0x13;      /* 8 bits, no parity, rcv IE, */
        !          1122:                                  /* no RTS control,char error mode */
        !          1123:        duart->modeA = 0x07;      /* 1 stop bit,CTS does not IE XMT */
        !          1124:                                  /* no RTS control,no echo or loop */
        !          1125:        duart->auxctl = 0x00;     /* baud rate set 1 */
        !          1126: 
        !          1127:        duart->clkselA = 0x99;    /* 4800 baud for kbd */
        !          1128: 
        !          1129:         /* reset everything for keyboard */
        !          1130: 
        !          1131:        for (bits = RESET_M; bits < START_BREAK; bits += 0x10)
        !          1132:            duart->cmdA = bits;
        !          1133: 
        !          1134:        duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */
        !          1135: 
        !          1136: /*--------------------------
        !          1137: * init keyboard defaults */
        !          1138: /*
        !          1139:        for (i = 500; i > 0; --i) {
        !          1140:            if ((status = duart->statusA) & XMT_RDY) {
        !          1141:                duart->dataA = LK_DEFAULTS;
        !          1142:                break;
        !          1143:            }
        !          1144:        }
        !          1145: 
        !          1146:        for (j = 0; j < 3; ++j) {
        !          1147:            for (i = 50000; i > 0; --i) {
        !          1148:                if ((status = duart->statusA) & RCV_RDY) {
        !          1149:                    status = duart->dataA;
        !          1150:                    break;
        !          1151:                }
        !          1152:            }
        !          1153:        }
        !          1154: 
        !          1155:        if (i == 0)
        !          1156:            printf("LK-201 init error\n");
        !          1157: */
        !          1158: 
        !          1159: /*--------
        !          1160: * exit */
        !          1161: 
        !          1162:        return(0);
        !          1163: 
        !          1164: } /* setup_input */
        !          1165: 
        !          1166: /**********************************************************************
        !          1167: *
        !          1168: *      wait_status()... delay for at least one display frame time
        !          1169: *
        !          1170: ***********************************************************************
        !          1171: *
        !          1172: *      calling convention:
        !          1173: *
        !          1174: *              wait_status(adder, mask);
        !          1175: *              struct *adder adder;
        !          1176: *              int mask;
        !          1177: *
        !          1178: *      return: BAD means that we timed out without ever seeing the
        !          1179: *                    vertical sync status bit
        !          1180: *              GOOD otherwise
        !          1181: *
        !          1182: **************/
        !          1183: 
        !          1184: wait_status(adder, mask)
        !          1185: register struct adder *adder;
        !          1186: register int mask;
        !          1187: {
        !          1188:        register short status;
        !          1189:        int i;
        !          1190: 
        !          1191:        for ( i = 10000, adder->status = 0
        !          1192:            ; i > 0  &&  !((status = adder->status) & mask)
        !          1193:            ; --i);
        !          1194: 
        !          1195:        if (i == 0) {
        !          1196:            printf("timeout polling for 0x%x in adder->status\n", mask);
        !          1197:            return(BAD);
        !          1198:        }
        !          1199: 
        !          1200:        return(GOOD);
        !          1201: 
        !          1202: } /* wait_status */
        !          1203: 
        !          1204: /**********************************************************************
        !          1205: *
        !          1206: *      write_ID()... write out onto the ID bus
        !          1207: *
        !          1208: ***********************************************************************
        !          1209: *
        !          1210: *      calling convention:
        !          1211: *
        !          1212: *              struct *adder adder;    ;pntr to ADDER structure
        !          1213: *              short adrs;             ;VIPER address
        !          1214: *              short data;             ;data to be written
        !          1215: *              write_ID(adder);
        !          1216: *
        !          1217: *      return: BAD means that we timed out waiting for status bits
        !          1218: *                    VIPER-access-specific status bits
        !          1219: *              GOOD otherwise
        !          1220: *
        !          1221: **************/
        !          1222: 
        !          1223: write_ID(adder, adrs, data)
        !          1224: register struct adder *adder;
        !          1225: register short adrs;
        !          1226: register short data;
        !          1227: {
        !          1228:        int i;
        !          1229:        short status;
        !          1230: 
        !          1231:        for ( i = 100000, adder->status = 0
        !          1232:            ; i > 0  &&  !((status = adder->status) & ADDRESS_COMPLETE)
        !          1233:            ; --i);
        !          1234: 
        !          1235:        if (i == 0)
        !          1236:            goto ERR;
        !          1237: 
        !          1238:        for ( i = 100000, adder->status = 0
        !          1239:            ; i > 0  &&  !((status = adder->status) & TX_READY)
        !          1240:            ; --i);
        !          1241: 
        !          1242:        if (i > 0) {
        !          1243:            adder->id_data = data;
        !          1244:            adder->command = ID_LOAD | adrs;
        !          1245:            return(GOOD);
        !          1246:        }
        !          1247: 
        !          1248: ERR:
        !          1249:        printf("timeout trying to write to VIPER\n");
        !          1250:        return(BAD);
        !          1251: 
        !          1252: } /* write_ID */

unix.superglobalmegacorp.com

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