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