Annotation of 43BSDReno/sys/vaxstand/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 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.