|
|
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.