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

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

unix.superglobalmegacorp.com

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