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