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

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

unix.superglobalmegacorp.com

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