home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / vax / stand / qvcons.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-09  |  10.9 KB  |  441 lines

  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.  *    @(#)qvcons.c    7.7 (Berkeley) 12/16/90
  34.  */
  35.  
  36. /*
  37.  *    derived from: @(#)qvcons.c    4.1 11/23/87
  38.  */
  39.  
  40. /************************************************************************
  41.  *                                    *
  42.  *            Copyright (c) 1985 by                *
  43.  *        Digital Equipment Corporation, Maynard, MA        *
  44.  *            All rights reserved.                *
  45.  *                                    *
  46.  *   This software is furnished under a license and may be used and    *
  47.  *   copied  only  in accordance with the terms of such license and    *
  48.  *   with the  inclusion  of  the  above  copyright  notice.   This    *
  49.  *   software  or  any  other copies thereof may not be provided or    *
  50.  *   otherwise made available to any other person.  No title to and    *
  51.  *   ownership of the software is hereby transferred.            *
  52.  *                                    *
  53.  *   This software is  derived  from  software  received  from  the    *
  54.  *   University    of   California,   Berkeley,   and   from   Bell    *
  55.  *   Laboratories.  Use, duplication, or disclosure is  subject  to    *
  56.  *   restrictions  under  license  agreements  with  University  of    *
  57.  *   California and with AT&T.                        *
  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.  
  68. /* ---------------------------------------------------------------------
  69.  * Modification History - moved to sccs log
  70.  *
  71.  *  7 Jul 84 --  rjl
  72.  *    Initial version to support the qvss as the system console
  73.  *    during the boot process.
  74.  *
  75.  * ---------------------------------------------------------------------
  76.  */
  77.  
  78. #include "sys/types.h"
  79. #define KERNEL
  80. #include "../uba/qvioctl.h"
  81. #undef KERNEL
  82. #include "../include/cpu.h"
  83.  
  84. /*
  85.  * MicroVAX-II q-bus memory base
  86.  */
  87. #define QMEMBASE 0x30000000
  88. #define QVMAXEVQ    64
  89. #define QVSSCSR 0x20001e80
  90.  
  91. /*
  92.  * Screen initialization tables. qv_def_scn is used as an index into the
  93.  * table to select the proper initialization parameters.
  94.  */
  95. int qv_def_scn = 1;            /* Screen initialization flag    */
  96.  
  97. char    qv_scrn_15[]= {
  98.     31,25,27,0142,31,13,30,31,4,15,040,0,0,0,0,0
  99. };
  100.  
  101. char    qv_scrn_19s[]= {
  102.     39,30,31,0264,55,5,54,54,4,15,040,0,0,0,0,0
  103. };
  104.  
  105. char    *qv_init_tbl[]= {
  106.     qv_scrn_15,
  107.     qv_scrn_19s,
  108. };
  109.  
  110. struct qv_info qv_scn_defaults[] = {
  111.     {0, {0, 0}, 0, {0, 0}, 0, 0, 30, 80, 768, 480, 768-16, 480-16,
  112.      0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4},
  113.     {0, {0, 0}, 0, {0, 0}, 0, 0, 55, 120, 960, 864, 960-16, 864-16,
  114.      0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4},
  115.     {0, {0, 0}, 0, {0, 0}, 0, 0, 56, 120,1024, 864,1024-16, 864-16,
  116.      0, 0, 0, 0, 0, QVMAXEVQ, 0, 0, {0, 0}, {0, 0, 0, 0}, 2, 4}
  117. };
  118.  
  119. struct qv_info  qv_scn;
  120.  
  121. struct qv_keyboard {
  122.     int shift;            /* state variables    */
  123.     int cntrl;
  124.     int lock;
  125.     char last;            /* last character    */
  126. } qv_keyboard;
  127.  
  128. int qvputc(),qvgetc();
  129.  
  130. /*
  131.  * Keyboard translation and font tables
  132.  */
  133. extern  char q_key[],q_shift_key[],*q_special[],q_font[];
  134. extern    short q_cursor[];
  135.  
  136. extern (*v_putc)(),(*v_getc)();
  137.  
  138. /*
  139.  * Routine called to init a qvss.
  140.  */
  141. qv_init()
  142. {
  143.     struct qvdevice *qvaddr = (struct qvdevice *)QVSSCSR;
  144.     char *qvssmem;
  145.     short *scanline;
  146.     int i;
  147.     short scan;
  148.     char *ptr;
  149.     extern int cpu;
  150.  
  151.         if( badaddr( qvaddr, sizeof(short) ) )
  152.                 return(0);
  153.  
  154.         if( qvaddr->qv_csr & QV_19INCH )
  155.                 qv_def_scn = 1;
  156.         else
  157.                 qv_def_scn = 0;
  158.         qv_scn = qv_scn_defaults[ qv_def_scn ];
  159.     qv_scn.qvaddr = qvaddr;
  160.  
  161.     /*
  162.      * Initialize the screen.
  163.      */
  164.     ptr = qv_init_tbl[ qv_def_scn ];
  165.     for( i=0 ; i<16 ; i++ ) {
  166.         qvaddr->qv_crtaddr = i;
  167.         qvaddr->qv_crtdata = *ptr++;
  168.     }
  169.  
  170.     /*
  171.      * Turn on the keyboard. 
  172.      */
  173.     qvaddr->qv_uartcmd = 0x15;    /* set mode pntr/enable rx/tx    */
  174.     qvaddr->qv_uartmode = 0x17;    /* noparity, 8-bit        */
  175.     qvaddr->qv_uartmode = 0x07;    /* 1 stop bit            */
  176.     qvaddr->qv_uartstatus = 0x99;    /* 4800 baud xmit/recv         */
  177.  
  178.     qvssmem = (char *)((qvaddr->qv_csr & QV_MEM_BANK) << 7);
  179.     if( cpu == VAX_630 )
  180.         qvssmem += QMEMBASE;
  181.  
  182.     qv_scn.bitmap = qvssmem;
  183.     qv_scn.scanmap = (short *)((int)qvssmem + ( 254 * 1024 ));
  184.     qv_scn.cursorbits = (short *)((int)qvssmem + ( 256 * 1024 ) - 32);
  185.  
  186.     /*
  187.      * Setup the cursor.
  188.      */
  189.     for( i=0 ; i<16 ; i++ )
  190.         qv_scn.cursorbits[i] = q_cursor[i];
  191.  
  192.     /*
  193.      * Clear the bit map
  194.      */
  195.     for( i=0 , ptr = qv_scn.bitmap ; i<254 ; i += 2 , ptr += 2048)
  196.         bzero( ptr, 2048 );
  197.     
  198.     /*
  199.      * Reinitialize the scanmap
  200.      */
  201.     scan = qv_scn.qvaddr->qv_csr & QV_MEM_BANK;
  202.     scanline = qv_scn.scanmap;
  203.     for(i = 0 ; i < qv_scn.max_y ; i++ )
  204.         *scanline++ = scan++;
  205.  
  206.     /*
  207.      * Home the cursor
  208.      */
  209.     qv_scn.row = qv_scn.col = 0;
  210.  
  211.     /*
  212.      * Turn it on.
  213.      */
  214.     v_getc = qvgetc;
  215.     v_putc = qvputc;
  216.     qvaddr->qv_csr |= QV_CUR_MODE | QV_VIDEO_ENA;
  217.     return 1;
  218. }
  219.  
  220. /*
  221.  * Routine to display a character on the screen.  The model used is a 
  222.  * glass tty.  It is assummed that the user will only use this emulation
  223.  * during system boot and that the screen will be eventually controlled
  224.  * by a window manager.
  225.  */
  226. qvputc( c )
  227. char c;
  228. {
  229.  
  230.     char *b_row, *f_row;
  231.     int i, j;
  232.     short *scanline;
  233.  
  234.     c &= 0x7f;
  235.  
  236.     switch ( c ) {
  237.     case '\t':                /* tab        */
  238.         for( j = 8 - (qv_scn.col & 0x7) ; j > 0 ; j-- )
  239.             qvputc( ' ' );
  240.         break;
  241.  
  242.     case '\r':                /* return    */
  243.         qv_scn.col = 0;
  244.         break;
  245.  
  246.     case '\010':                /* backspace    */
  247.         if( --qv_scn.col < 0 )
  248.             qv_scn.col = 0;
  249.         break;
  250.  
  251.     case '\n':                /* linefeed    */
  252.         if( qv_scn.row+1 >= qv_scn.max_row )
  253.             qvscroll();
  254.         else
  255.             qv_scn.row++;
  256.         break;
  257.  
  258.     case '\007':                /* bell        */
  259.         if( qv_scn.qvaddr )
  260.             qv_key_out( LK_BELL_ENABLE );
  261.         return;
  262.  
  263.     default:
  264.         if( c >= ' ' && c <= '~' ) {
  265.             scanline = qv_scn.scanmap;
  266.             b_row = qv_scn.bitmap+(scanline[qv_scn.row*15]&0x3ff)*128+qv_scn.col;
  267.             i = c - ' ';
  268.             if( i < 0 || i > 95 )
  269.                 i = 0;
  270.             else
  271.                 i *= 15;
  272.             f_row = (char *)((int)q_font + i);
  273.         
  274.             for( i=0 ; i<15 ; i++ , b_row += 128, f_row++ )
  275.                 *b_row = *f_row;
  276.  
  277.             if( ++qv_scn.col >= qv_scn.max_col ) {
  278.                 qv_scn.col = 0 ;
  279.                 if( qv_scn.row+1 >= qv_scn.max_row )
  280.                     qvscroll();
  281.                 else
  282.                     qv_scn.row++;
  283.             }
  284.         }
  285.         break;
  286.     }
  287.     /*
  288.      * Position the cursor to the next character location.
  289.      */
  290.     qv_pos_cur( qv_scn.col*8, qv_scn.row*15 );
  291. }
  292.  
  293. /*
  294.  * Position the cursor to a particular spot.
  295.  */
  296. qv_pos_cur( x, y)
  297. int x,y;
  298. {
  299.     struct qvdevice *qvaddr;
  300.  
  301.     if( qvaddr = qv_scn.qvaddr ) {
  302.         if( y < 0 || y > qv_scn.max_cur_y )
  303.             y = qv_scn.max_cur_y;
  304.         if( x < 0 || x > qv_scn.max_cur_x )
  305.             x = qv_scn.max_cur_x;
  306.  
  307.         qvaddr->qv_crtaddr = 10;    /* select cursor start reg */
  308.         qvaddr->qv_crtdata = y & 0xf;
  309.         qvaddr->qv_crtaddr = 11;    /* select cursor end reg */
  310.         qvaddr->qv_crtdata = y & 0xf;
  311.         qvaddr->qv_crtaddr = 14;    /* select cursor y pos. */
  312.         qvaddr->qv_crtdata = y >> 4;
  313.         qvaddr->qv_xcur = x;        /* pos x axis    */
  314.     }
  315. }
  316. /*
  317.  * Scroll the bitmap by moving the scanline map words. This could
  318.  * be done by moving the bitmap but it's much too slow for a full screen.
  319.  * The only drawback is that the scanline map must be reset when the user 
  320.  * wants to do graphics.
  321.  */
  322. qvscroll()
  323. {
  324.     int i;
  325.     short tmpscanlines[15];
  326.     char *b_row;
  327.     short *scanline;
  328.  
  329.  
  330.     /*
  331.      * Save the first 15 scanlines so that we can put them at
  332.      * the bottom when done.
  333.      */
  334.     bcopy( qv_scn.scanmap, tmpscanlines, sizeof tmpscanlines );
  335.  
  336.     /*
  337.      * Clear the wrapping line so that it won't flash on the bottom
  338.      * of the screen.
  339.      */
  340.     scanline = qv_scn.scanmap;
  341.     b_row = qv_scn.bitmap+(*scanline&0x3ff)*128;
  342.     bzero( b_row, 1920 );
  343.  
  344.     /*
  345.      * Now move the scanlines down 
  346.      */
  347.     bcopy( qv_scn.scanmap+15, qv_scn.scanmap, (qv_scn.row * 15) * sizeof (short) );
  348.  
  349.     /*
  350.      * Now put the other lines back
  351.      */
  352.     bcopy( tmpscanlines, qv_scn.scanmap+(qv_scn.row * 15), sizeof tmpscanlines );
  353.  
  354. }
  355.  
  356. /*
  357.  * QVSS keyboard interrupt.
  358.  */
  359. qvgetc()
  360. {
  361.     int c;
  362.     struct qvdevice *qvaddr;
  363.     char *string;
  364.     int j;
  365.  
  366.     qvaddr = qv_scn.qvaddr;
  367.     /*
  368.      * Get a character from the keyboard.
  369.      */
  370. loop:
  371.     while( (qvaddr->qv_uartstatus & 0x01) == 0 )
  372.         ;
  373.     j = qvaddr->qv_uartdata & 0xff;
  374.     /*
  375.      * See if its a state change key
  376.      */
  377.     switch ( j ) {
  378.     case LOCK:
  379.         qv_keyboard.lock ^= 0xffff;    /* toggle */
  380.         if( qv_keyboard.lock )
  381.             qv_key_out( LK_LED_ENABLE );
  382.         else
  383.             qv_key_out( LK_LED_DISABLE );
  384.         qv_key_out( LED_3 );
  385.         goto loop;
  386.     case SHIFT:
  387.         qv_keyboard.shift ^= 0xffff;
  388.         goto loop;
  389.     case CNTRL:
  390.         qv_keyboard.cntrl ^= 0xffff;
  391.         goto loop;
  392.     case ALLUP:
  393.         qv_keyboard.cntrl = qv_keyboard.shift = 0;
  394.         goto loop;
  395.     case REPEAT:
  396.         c = qv_keyboard.last;
  397.         break;
  398.     default:
  399.         /*
  400.          * Test for control characters. If set, see if the character
  401.          * is elligible to become a control character.
  402.          */
  403.         if( qv_keyboard.cntrl ) {
  404.             c = q_key[ j ];
  405.             if( c >= ' ' && c <= '~' )
  406.                 c &= 0x1f;
  407.         } else if( qv_keyboard.lock || qv_keyboard.shift )
  408.             c = q_shift_key[ j ];
  409.         else
  410.             c = q_key[ j ];
  411.         break;
  412.     }
  413.  
  414.     qv_keyboard.last = c;
  415.  
  416.     /*
  417.      * Check for special function keys
  418.      */
  419.     if( c & 0x80 ) 
  420.         return 0;
  421.     else
  422.         return c;
  423. }
  424.  
  425. /*
  426.  * Output to the keyboard. This routine status polls the transmitter on the
  427.  * keyboard to output a code. The timer is to avoid hanging on a bad device.
  428.  */
  429. qv_key_out( c )
  430. char c;
  431. {
  432.     int timer = 30000;
  433.  
  434.     if( qv_scn.qvaddr ) {
  435.         while( (qv_scn.qvaddr->qv_uartstatus & 0x4) == 0  && timer-- )
  436.             ;
  437.         qv_scn.qvaddr->qv_uartdata = c;
  438.     }
  439. }
  440.  
  441.