Annotation of Net2/arch/vax/stand/qdcons.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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