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