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