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