|
|
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: * @(#)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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.