BSD 4_3_Net_2 release
[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 *
af359dea
C
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.
42a69a9d 20 *
af359dea
C
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
c0441c16
KB
34 */
35
36/*
42a69a9d
MT
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
b28b3a13 78#include "sys/types.h"
42a69a9d 79#define KERNEL
b28b3a13 80#include "../uba/qvioctl.h"
42a69a9d 81#undef KERNEL
b28b3a13 82#include "../include/cpu.h"
42a69a9d
MT
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 */
95int qv_def_scn = 1; /* Screen initialization flag */
96
97char qv_scrn_15[]= {
98 31,25,27,0142,31,13,30,31,4,15,040,0,0,0,0,0
99};
100
101char qv_scrn_19s[]= {
102 39,30,31,0264,55,5,54,54,4,15,040,0,0,0,0,0
103};
104
105char *qv_init_tbl[]= {
106 qv_scrn_15,
107 qv_scrn_19s,
108};
109
110struct 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
119struct qv_info qv_scn;
120
121struct qv_keyboard {
122 int shift; /* state variables */
123 int cntrl;
124 int lock;
125 char last; /* last character */
126} qv_keyboard;
127
128int qvputc(),qvgetc();
129
130/*
131 * Keyboard translation and font tables
132 */
133extern char q_key[],q_shift_key[],*q_special[],q_font[];
134extern short q_cursor[];
135
136extern (*v_putc)(),(*v_getc)();
137
138/*
139 * Routine called to init a qvss.
140 */
141qv_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 */
226qvputc( c )
227char 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 */
296qv_pos_cur( x, y)
297int 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 */
322qvscroll()
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 */
359qvgetc()
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 */
370loop:
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 */
429qv_key_out( c )
430char 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