xref: /csrg-svn/sys/pmax/dev/fb.c (revision 56814)
1*56814Sralph /*-
2*56814Sralph  * Copyright (c) 1992 The Regents of the University of California.
3*56814Sralph  * All rights reserved.
4*56814Sralph  *
5*56814Sralph  * This code is derived from software contributed to Berkeley by
6*56814Sralph  * Ralph Campbell and Rick Macklem.
7*56814Sralph  *
8*56814Sralph  * %sccs.include.redist.c%
9*56814Sralph  *
10*56814Sralph  *	@(#)fb.c	7.1 (Berkeley) 11/15/92
11*56814Sralph  */
12*56814Sralph 
13*56814Sralph /*
14*56814Sralph  *  devGraphics.c --
15*56814Sralph  *
16*56814Sralph  *     	This file contains machine-dependent routines for the graphics device.
17*56814Sralph  *
18*56814Sralph  *	Copyright (C) 1989 Digital Equipment Corporation.
19*56814Sralph  *	Permission to use, copy, modify, and distribute this software and
20*56814Sralph  *	its documentation for any purpose and without fee is hereby granted,
21*56814Sralph  *	provided that the above copyright notice appears in all copies.
22*56814Sralph  *	Digital Equipment Corporation makes no representations about the
23*56814Sralph  *	suitability of this software for any purpose.  It is provided "as is"
24*56814Sralph  *	without express or implied warranty.
25*56814Sralph  *
26*56814Sralph  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
27*56814Sralph  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
28*56814Sralph  */
29*56814Sralph 
30*56814Sralph /*
31*56814Sralph  * This file has all the routines common to the various frame buffer drivers
32*56814Sralph  * including a generic ioctl routine. The pmax_fb structure is passed into the
33*56814Sralph  * routines and has device specifics stored in it.
34*56814Sralph  * The LK201 keycode mapping routine is also here along with initialization
35*56814Sralph  * functions for the keyboard and mouse.
36*56814Sralph  */
37*56814Sralph 
38*56814Sralph #include <sys/param.h>
39*56814Sralph #include <sys/systm.h>
40*56814Sralph #include <sys/ioctl.h>
41*56814Sralph #include <sys/tty.h>
42*56814Sralph #include <sys/time.h>
43*56814Sralph #include <sys/kernel.h>
44*56814Sralph #include <sys/ioctl.h>
45*56814Sralph #include <sys/file.h>
46*56814Sralph #include <sys/errno.h>
47*56814Sralph #include <sys/proc.h>
48*56814Sralph #include <sys/mman.h>
49*56814Sralph #include <sys/syslog.h>
50*56814Sralph 
51*56814Sralph #include <vm/vm.h>
52*56814Sralph 
53*56814Sralph #include <machine/machConst.h>
54*56814Sralph #include <machine/pmioctl.h>
55*56814Sralph #include <machine/dc7085cons.h>
56*56814Sralph 
57*56814Sralph #include <pmax/dev/device.h>
58*56814Sralph #include <pmax/dev/font.c>
59*56814Sralph #include <pmax/dev/sccreg.h>
60*56814Sralph #include <pmax/dev/fbreg.h>
61*56814Sralph 
62*56814Sralph #include <pmax/stand/dec_prom.h>
63*56814Sralph 
64*56814Sralph #include <pmax/pmax/cons.h>
65*56814Sralph #include <pmax/pmax/pmaxtype.h>
66*56814Sralph 
67*56814Sralph void fbKbdEvent(), fbMouseEvent(), fbMouseButtons(), fbScroll();
68*56814Sralph void fbBlitc(), fbPutc();
69*56814Sralph extern int pmax_boardtype;
70*56814Sralph extern struct consdev cn_tab;
71*56814Sralph #include "dc.h"
72*56814Sralph #if NDC > 0
73*56814Sralph extern int dcGetc(), dcparam();
74*56814Sralph extern void dcPutc();
75*56814Sralph #endif
76*56814Sralph #include "scc.h"
77*56814Sralph #if NSCC > 0
78*56814Sralph extern int sccGetc(), sccparam();
79*56814Sralph extern void sccPutc();
80*56814Sralph #endif
81*56814Sralph 
82*56814Sralph /*
83*56814Sralph  * The default cursor.
84*56814Sralph  */
85*56814Sralph u_short defCursor[32] = {
86*56814Sralph /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
87*56814Sralph 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
88*56814Sralph /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
89*56814Sralph               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
90*56814Sralph 
91*56814Sralph };
92*56814Sralph 
93*56814Sralph /*
94*56814Sralph  * Font mask bits used by fbBlitc().
95*56814Sralph  */
96*56814Sralph static unsigned int fontmaskBits[16] = {
97*56814Sralph 	0x00000000,
98*56814Sralph 	0x00000001,
99*56814Sralph 	0x00000100,
100*56814Sralph 	0x00000101,
101*56814Sralph 	0x00010000,
102*56814Sralph 	0x00010001,
103*56814Sralph 	0x00010100,
104*56814Sralph 	0x00010101,
105*56814Sralph 	0x01000000,
106*56814Sralph 	0x01000001,
107*56814Sralph 	0x01000100,
108*56814Sralph 	0x01000101,
109*56814Sralph 	0x01010000,
110*56814Sralph 	0x01010001,
111*56814Sralph 	0x01010100,
112*56814Sralph 	0x01010101
113*56814Sralph };
114*56814Sralph 
115*56814Sralph /*
116*56814Sralph  * Ascii values of command keys.
117*56814Sralph  */
118*56814Sralph #define KBD_TAB		'\t'
119*56814Sralph #define KBD_DEL		127
120*56814Sralph #define KBD_RET		'\r'
121*56814Sralph 
122*56814Sralph /*
123*56814Sralph  *  Define "hardware-independent" codes for the control, shift, meta and
124*56814Sralph  *  function keys.  Codes start after the last 7-bit ASCII code (127)
125*56814Sralph  *  and are assigned in an arbitrary order.
126*56814Sralph  */
127*56814Sralph #define KBD_NOKEY	128
128*56814Sralph 
129*56814Sralph #define KBD_F1		201
130*56814Sralph #define KBD_F2		202
131*56814Sralph #define KBD_F3		203
132*56814Sralph #define KBD_F4		204
133*56814Sralph #define KBD_F5		205
134*56814Sralph #define KBD_F6		206
135*56814Sralph #define KBD_F7		207
136*56814Sralph #define KBD_F8		208
137*56814Sralph #define KBD_F9		209
138*56814Sralph #define KBD_F10		210
139*56814Sralph #define KBD_F11		211
140*56814Sralph #define KBD_F12		212
141*56814Sralph #define KBD_F13		213
142*56814Sralph #define KBD_F14		214
143*56814Sralph #define KBD_HELP	215
144*56814Sralph #define KBD_DO		216
145*56814Sralph #define KBD_F17		217
146*56814Sralph #define KBD_F18		218
147*56814Sralph #define KBD_F19		219
148*56814Sralph #define KBD_F20		220
149*56814Sralph 
150*56814Sralph #define KBD_FIND	221
151*56814Sralph #define KBD_INSERT	222
152*56814Sralph #define KBD_REMOVE	223
153*56814Sralph #define KBD_SELECT	224
154*56814Sralph #define KBD_PREVIOUS	225
155*56814Sralph #define KBD_NEXT	226
156*56814Sralph 
157*56814Sralph #define KBD_KP_ENTER	227
158*56814Sralph #define KBD_KP_F1	228
159*56814Sralph #define KBD_KP_F2	229
160*56814Sralph #define KBD_KP_F3	230
161*56814Sralph #define KBD_KP_F4	231
162*56814Sralph #define KBD_LEFT	232
163*56814Sralph #define KBD_RIGHT	233
164*56814Sralph #define KBD_DOWN	234
165*56814Sralph #define KBD_UP		235
166*56814Sralph 
167*56814Sralph #define KBD_CONTROL	236
168*56814Sralph #define KBD_SHIFT	237
169*56814Sralph #define KBD_CAPSLOCK	238
170*56814Sralph #define KBD_ALTERNATE	239
171*56814Sralph 
172*56814Sralph /*
173*56814Sralph  * Keyboard to Ascii, unshifted.
174*56814Sralph  */
175*56814Sralph static unsigned char unshiftedAscii[] = {
176*56814Sralph /*  0 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
177*56814Sralph /*  4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
178*56814Sralph /*  8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
179*56814Sralph /*  c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
180*56814Sralph /* 10 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
181*56814Sralph /* 14 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
182*56814Sralph /* 18 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
183*56814Sralph /* 1c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
184*56814Sralph /* 20 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
185*56814Sralph /* 24 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
186*56814Sralph /* 28 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
187*56814Sralph /* 2c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
188*56814Sralph /* 30 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
189*56814Sralph /* 34 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
190*56814Sralph /* 38 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
191*56814Sralph /* 3c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
192*56814Sralph /* 40 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
193*56814Sralph /* 44 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
194*56814Sralph /* 48 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
195*56814Sralph /* 4c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
196*56814Sralph /* 50 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
197*56814Sralph /* 54 */ KBD_NOKEY,	KBD_NOKEY,	KBD_F1,		KBD_F2,
198*56814Sralph /* 58 */ KBD_F3,	KBD_F4,		KBD_F5,		KBD_NOKEY,
199*56814Sralph /* 5c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
200*56814Sralph /* 60 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
201*56814Sralph /* 64 */ KBD_F6,	KBD_F7,		KBD_F8,		KBD_F9,
202*56814Sralph /* 68 */ KBD_F10,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
203*56814Sralph /* 6c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
204*56814Sralph /* 70 */ KBD_NOKEY,	'\033',		KBD_F12,	KBD_F13,
205*56814Sralph /* 74 */ KBD_F14,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
206*56814Sralph /* 78 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
207*56814Sralph /* 7c */ KBD_HELP,	KBD_DO,		KBD_NOKEY,	KBD_NOKEY,
208*56814Sralph /* 80 */ KBD_F17,	KBD_F18,	KBD_F19,	KBD_F20,
209*56814Sralph /* 84 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
210*56814Sralph /* 88 */ KBD_NOKEY,	KBD_NOKEY,	KBD_FIND,	KBD_INSERT,
211*56814Sralph /* 8c */ KBD_REMOVE,	KBD_SELECT,	KBD_PREVIOUS,	KBD_NEXT,
212*56814Sralph /* 90 */ KBD_NOKEY,	KBD_NOKEY,	'0',		KBD_NOKEY,
213*56814Sralph /* 94 */ '.',		KBD_KP_ENTER,	'1',		'2',
214*56814Sralph /* 98 */ '3',		'4',		'5',		'6',
215*56814Sralph /* 9c */ ',',		'7',		'8',		'9',
216*56814Sralph /* a0 */ '-',		KBD_KP_F1,	KBD_KP_F2,	KBD_KP_F3,
217*56814Sralph /* a4 */ KBD_KP_F4,	KBD_NOKEY,	KBD_NOKEY,	KBD_LEFT,
218*56814Sralph /* a8 */ KBD_RIGHT,	KBD_DOWN, 	KBD_UP,		KBD_NOKEY,
219*56814Sralph /* ac */ KBD_NOKEY,	KBD_NOKEY,	KBD_SHIFT,	KBD_CONTROL,
220*56814Sralph /* b0 */ KBD_CAPSLOCK,	KBD_ALTERNATE,	KBD_NOKEY,	KBD_NOKEY,
221*56814Sralph /* b4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
222*56814Sralph /* b8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
223*56814Sralph /* bc */ KBD_DEL,	KBD_RET,	KBD_TAB,	'`',
224*56814Sralph /* c0 */ '1',		'q',		'a',		'z',
225*56814Sralph /* c4 */ KBD_NOKEY,	'2',		'w',		's',
226*56814Sralph /* c8 */ 'x',		'<',		KBD_NOKEY,	'3',
227*56814Sralph /* cc */ 'e',		'd',		'c',		KBD_NOKEY,
228*56814Sralph /* d0 */ '4',		'r',		'f',		'v',
229*56814Sralph /* d4 */ ' ',		KBD_NOKEY,	'5',		't',
230*56814Sralph /* d8 */ 'g',		'b',		KBD_NOKEY,	'6',
231*56814Sralph /* dc */ 'y',		'h',		'n',		KBD_NOKEY,
232*56814Sralph /* e0 */ '7',		'u',		'j',		'm',
233*56814Sralph /* e4 */ KBD_NOKEY,	'8',		'i',		'k',
234*56814Sralph /* e8 */ ',',		KBD_NOKEY,	'9',		'o',
235*56814Sralph /* ec */ 'l',		'.',		KBD_NOKEY,	'0',
236*56814Sralph /* f0 */ 'p',		KBD_NOKEY,	';',		'/',
237*56814Sralph /* f4 */ KBD_NOKEY,	'=',		']',		'\\',
238*56814Sralph /* f8 */ KBD_NOKEY,	'-',		'[',		'\'',
239*56814Sralph /* fc */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
240*56814Sralph };
241*56814Sralph 
242*56814Sralph /*
243*56814Sralph  * Keyboard to Ascii, shifted.
244*56814Sralph  */
245*56814Sralph static unsigned char shiftedAscii[] = {
246*56814Sralph /*  0 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
247*56814Sralph /*  4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
248*56814Sralph /*  8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
249*56814Sralph /*  c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
250*56814Sralph /* 10 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
251*56814Sralph /* 14 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
252*56814Sralph /* 18 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
253*56814Sralph /* 1c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
254*56814Sralph /* 20 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
255*56814Sralph /* 24 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
256*56814Sralph /* 28 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
257*56814Sralph /* 2c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
258*56814Sralph /* 30 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
259*56814Sralph /* 34 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
260*56814Sralph /* 38 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
261*56814Sralph /* 3c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
262*56814Sralph /* 40 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
263*56814Sralph /* 44 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
264*56814Sralph /* 48 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
265*56814Sralph /* 4c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
266*56814Sralph /* 50 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
267*56814Sralph /* 54 */ KBD_NOKEY,	KBD_NOKEY,	KBD_F1,		KBD_F2,
268*56814Sralph /* 58 */ KBD_F3,	KBD_F4,		KBD_F5,		KBD_NOKEY,
269*56814Sralph /* 5c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
270*56814Sralph /* 60 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
271*56814Sralph /* 64 */ KBD_F6,	KBD_F7,		KBD_F8,		KBD_F9,
272*56814Sralph /* 68 */ KBD_F10,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
273*56814Sralph /* 6c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
274*56814Sralph /* 70 */ KBD_NOKEY,	KBD_F11,	KBD_F12,	KBD_F13,
275*56814Sralph /* 74 */ KBD_F14,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
276*56814Sralph /* 78 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
277*56814Sralph /* 7c */ KBD_HELP,	KBD_DO,		KBD_NOKEY,	KBD_NOKEY,
278*56814Sralph /* 80 */ KBD_F17,	KBD_F18,	KBD_F19,	KBD_F20,
279*56814Sralph /* 84 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
280*56814Sralph /* 88 */ KBD_NOKEY,	KBD_NOKEY,	KBD_FIND,	KBD_INSERT,
281*56814Sralph /* 8c */ KBD_REMOVE,	KBD_SELECT,	KBD_PREVIOUS,	KBD_NEXT,
282*56814Sralph /* 90 */ KBD_NOKEY,	KBD_NOKEY,	'0',		KBD_NOKEY,
283*56814Sralph /* 94 */ '.',		KBD_KP_ENTER,	'1',		'2',
284*56814Sralph /* 98 */ '3',		'4',		'5',		'6',
285*56814Sralph /* 9c */ ',',		'7',		'8',		'9',
286*56814Sralph /* a0 */ '-',		KBD_KP_F1,	KBD_KP_F2,	KBD_KP_F3,
287*56814Sralph /* a4 */ KBD_KP_F4,	KBD_NOKEY,	KBD_NOKEY,	KBD_LEFT,
288*56814Sralph /* a8 */ KBD_RIGHT,	KBD_DOWN, 	KBD_UP,		KBD_NOKEY,
289*56814Sralph /* ac */ KBD_NOKEY,	KBD_NOKEY,	KBD_SHIFT,	KBD_CONTROL,
290*56814Sralph /* b0 */ KBD_CAPSLOCK,	KBD_ALTERNATE,	KBD_NOKEY,	KBD_NOKEY,
291*56814Sralph /* b4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
292*56814Sralph /* b8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
293*56814Sralph /* bc */ KBD_DEL,	KBD_RET,	KBD_TAB,	'~',
294*56814Sralph /* c0 */ '!',		'q',		'a',		'z',
295*56814Sralph /* c4 */ KBD_NOKEY,	'@',		'w',		's',
296*56814Sralph /* c8 */ 'x',		'>',		KBD_NOKEY,	'#',
297*56814Sralph /* cc */ 'e',		'd',		'c',		KBD_NOKEY,
298*56814Sralph /* d0 */ '$',		'r',		'f',		'v',
299*56814Sralph /* d4 */ ' ',		KBD_NOKEY,	'%',		't',
300*56814Sralph /* d8 */ 'g',		'b',		KBD_NOKEY,	'^',
301*56814Sralph /* dc */ 'y',		'h',		'n',		KBD_NOKEY,
302*56814Sralph /* e0 */ '&',		'u',		'j',		'm',
303*56814Sralph /* e4 */ KBD_NOKEY,	'*',		'i',		'k',
304*56814Sralph /* e8 */ '<',		KBD_NOKEY,	'(',		'o',
305*56814Sralph /* ec */ 'l',		'>',		KBD_NOKEY,	')',
306*56814Sralph /* f0 */ 'p',		KBD_NOKEY,	':',		'?',
307*56814Sralph /* f4 */ KBD_NOKEY,	'+',		'}',		'|',
308*56814Sralph /* f8 */ KBD_NOKEY,	'_',		'{',		'"',
309*56814Sralph /* fc */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
310*56814Sralph };
311*56814Sralph 
312*56814Sralph /*
313*56814Sralph  * Keyboard initialization string.
314*56814Sralph  */
315*56814Sralph static u_char kbdInitString[] = {
316*56814Sralph 	LK_LED_ENABLE, LED_ALL,		/* show we are resetting keyboard */
317*56814Sralph 	LK_DEFAULTS,
318*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 1),
319*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 2),
320*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 3),
321*56814Sralph 	LK_CMD_MODE(LK_DOWN, 4),	/* could also be LK_AUTODOWN */
322*56814Sralph 	LK_CMD_MODE(LK_UPDOWN, 5),
323*56814Sralph 	LK_CMD_MODE(LK_UPDOWN, 6),
324*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 7),
325*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 8),
326*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 9),
327*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 10),
328*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 11),
329*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 12),
330*56814Sralph 	LK_CMD_MODE(LK_DOWN, 13),
331*56814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 14),
332*56814Sralph 	LK_AR_ENABLE,			/* we want autorepeat by default */
333*56814Sralph 	LK_CL_ENABLE, 0x83,		/* keyclick, volume */
334*56814Sralph 	LK_KBD_ENABLE,			/* the keyboard itself */
335*56814Sralph 	LK_BELL_ENABLE, 0x83,		/* keyboard bell, volume */
336*56814Sralph 	LK_LED_DISABLE, LED_ALL,	/* clear keyboard leds */
337*56814Sralph };
338*56814Sralph 
339*56814Sralph /*
340*56814Sralph  *----------------------------------------------------------------------
341*56814Sralph  *
342*56814Sralph  * fbKbdEvent --
343*56814Sralph  *
344*56814Sralph  *	Process a received character.
345*56814Sralph  *
346*56814Sralph  * Results:
347*56814Sralph  *	None.
348*56814Sralph  *
349*56814Sralph  * Side effects:
350*56814Sralph  *	Events added to the queue.
351*56814Sralph  *
352*56814Sralph  *----------------------------------------------------------------------
353*56814Sralph  */
354*56814Sralph void
355*56814Sralph fbKbdEvent(ch, fp)
356*56814Sralph 	int ch;
357*56814Sralph 	register struct pmax_fb *fp;
358*56814Sralph {
359*56814Sralph 	register pmEvent *eventPtr;
360*56814Sralph 	int i;
361*56814Sralph 
362*56814Sralph 	if (!fp->GraphicsOpen)
363*56814Sralph 		return;
364*56814Sralph 
365*56814Sralph 	/*
366*56814Sralph 	 * See if there is room in the queue.
367*56814Sralph 	 */
368*56814Sralph 	i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1);
369*56814Sralph 	if (i == fp->fbu->scrInfo.qe.eHead)
370*56814Sralph 		return;
371*56814Sralph 
372*56814Sralph 	/*
373*56814Sralph 	 * Add the event to the queue.
374*56814Sralph 	 */
375*56814Sralph 	eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
376*56814Sralph 	eventPtr->type = BUTTON_RAW_TYPE;
377*56814Sralph 	eventPtr->device = KEYBOARD_DEVICE;
378*56814Sralph 	eventPtr->x = fp->fbu->scrInfo.mouse.x;
379*56814Sralph 	eventPtr->y = fp->fbu->scrInfo.mouse.y;
380*56814Sralph 	eventPtr->time = TO_MS(time);
381*56814Sralph 	eventPtr->key = ch;
382*56814Sralph 	fp->fbu->scrInfo.qe.eTail = i;
383*56814Sralph 	selwakeup(&fp->selp);
384*56814Sralph }
385*56814Sralph 
386*56814Sralph /*
387*56814Sralph  *----------------------------------------------------------------------
388*56814Sralph  *
389*56814Sralph  * fbMouseEvent --
390*56814Sralph  *
391*56814Sralph  *	Process a mouse event.
392*56814Sralph  *
393*56814Sralph  * Results:
394*56814Sralph  *	None.
395*56814Sralph  *
396*56814Sralph  * Side effects:
397*56814Sralph  *	An event is added to the event queue.
398*56814Sralph  *
399*56814Sralph  *----------------------------------------------------------------------
400*56814Sralph  */
401*56814Sralph void
402*56814Sralph fbMouseEvent(newRepPtr, fp)
403*56814Sralph 	register MouseReport *newRepPtr;
404*56814Sralph 	register struct pmax_fb *fp;
405*56814Sralph {
406*56814Sralph 	unsigned milliSec;
407*56814Sralph 	int i;
408*56814Sralph 	pmEvent *eventPtr;
409*56814Sralph 
410*56814Sralph 	if (!fp->GraphicsOpen)
411*56814Sralph 		return;
412*56814Sralph 
413*56814Sralph 	milliSec = TO_MS(time);
414*56814Sralph 
415*56814Sralph 	/*
416*56814Sralph 	 * Check to see if we have to accelerate the mouse
417*56814Sralph 	 */
418*56814Sralph 	if (fp->fbu->scrInfo.mscale >= 0) {
419*56814Sralph 		if (newRepPtr->dx >= fp->fbu->scrInfo.mthreshold) {
420*56814Sralph 			newRepPtr->dx +=
421*56814Sralph 				(newRepPtr->dx - fp->fbu->scrInfo.mthreshold) *
422*56814Sralph 				fp->fbu->scrInfo.mscale;
423*56814Sralph 		}
424*56814Sralph 		if (newRepPtr->dy >= fp->fbu->scrInfo.mthreshold) {
425*56814Sralph 			newRepPtr->dy +=
426*56814Sralph 				(newRepPtr->dy - fp->fbu->scrInfo.mthreshold) *
427*56814Sralph 				fp->fbu->scrInfo.mscale;
428*56814Sralph 		}
429*56814Sralph 	}
430*56814Sralph 
431*56814Sralph 	/*
432*56814Sralph 	 * Update mouse position
433*56814Sralph 	 */
434*56814Sralph 	if (newRepPtr->state & MOUSE_X_SIGN) {
435*56814Sralph 		fp->fbu->scrInfo.mouse.x += newRepPtr->dx;
436*56814Sralph 		if (fp->fbu->scrInfo.mouse.x > fp->fbu->scrInfo.max_cur_x)
437*56814Sralph 			fp->fbu->scrInfo.mouse.x = fp->fbu->scrInfo.max_cur_x;
438*56814Sralph 	} else {
439*56814Sralph 		fp->fbu->scrInfo.mouse.x -= newRepPtr->dx;
440*56814Sralph 		if (fp->fbu->scrInfo.mouse.x < fp->fbu->scrInfo.min_cur_x)
441*56814Sralph 			fp->fbu->scrInfo.mouse.x = fp->fbu->scrInfo.min_cur_x;
442*56814Sralph 	}
443*56814Sralph 	if (newRepPtr->state & MOUSE_Y_SIGN) {
444*56814Sralph 		fp->fbu->scrInfo.mouse.y -= newRepPtr->dy;
445*56814Sralph 		if (fp->fbu->scrInfo.mouse.y < fp->fbu->scrInfo.min_cur_y)
446*56814Sralph 			fp->fbu->scrInfo.mouse.y = fp->fbu->scrInfo.min_cur_y;
447*56814Sralph 	} else {
448*56814Sralph 		fp->fbu->scrInfo.mouse.y += newRepPtr->dy;
449*56814Sralph 		if (fp->fbu->scrInfo.mouse.y > fp->fbu->scrInfo.max_cur_y)
450*56814Sralph 			fp->fbu->scrInfo.mouse.y = fp->fbu->scrInfo.max_cur_y;
451*56814Sralph 	}
452*56814Sralph 
453*56814Sralph 	/*
454*56814Sralph 	 * Move the hardware cursor.
455*56814Sralph 	 */
456*56814Sralph 	(*fp->posCursor)(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
457*56814Sralph 
458*56814Sralph 	/*
459*56814Sralph 	 * Store the motion event in the motion buffer.
460*56814Sralph 	 */
461*56814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].time = milliSec;
462*56814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].x = fp->fbu->scrInfo.mouse.x;
463*56814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].y = fp->fbu->scrInfo.mouse.y;
464*56814Sralph 	if (++fp->fbu->scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
465*56814Sralph 		fp->fbu->scrInfo.qe.tcNext = 0;
466*56814Sralph 	if (fp->fbu->scrInfo.mouse.y < fp->fbu->scrInfo.mbox.bottom &&
467*56814Sralph 	    fp->fbu->scrInfo.mouse.y >=  fp->fbu->scrInfo.mbox.top &&
468*56814Sralph 	    fp->fbu->scrInfo.mouse.x < fp->fbu->scrInfo.mbox.right &&
469*56814Sralph 	    fp->fbu->scrInfo.mouse.x >=  fp->fbu->scrInfo.mbox.left)
470*56814Sralph 		return;
471*56814Sralph 
472*56814Sralph 	fp->fbu->scrInfo.mbox.bottom = 0;
473*56814Sralph 	if (PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1) == fp->fbu->scrInfo.qe.eHead)
474*56814Sralph 		return;
475*56814Sralph 
476*56814Sralph 	i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail - 1);
477*56814Sralph 	if ((fp->fbu->scrInfo.qe.eTail != fp->fbu->scrInfo.qe.eHead) &&
478*56814Sralph 	    (i != fp->fbu->scrInfo.qe.eHead)) {
479*56814Sralph 		pmEvent *eventPtr;
480*56814Sralph 
481*56814Sralph 		eventPtr = &fp->fbu->events[i];
482*56814Sralph 		if (eventPtr->type == MOTION_TYPE) {
483*56814Sralph 			eventPtr->x = fp->fbu->scrInfo.mouse.x;
484*56814Sralph 			eventPtr->y = fp->fbu->scrInfo.mouse.y;
485*56814Sralph 			eventPtr->time = milliSec;
486*56814Sralph 			eventPtr->device = MOUSE_DEVICE;
487*56814Sralph 			return;
488*56814Sralph 		}
489*56814Sralph 	}
490*56814Sralph 	/*
491*56814Sralph 	 * Put event into queue and wakeup any waiters.
492*56814Sralph 	 */
493*56814Sralph 	eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
494*56814Sralph 	eventPtr->type = MOTION_TYPE;
495*56814Sralph 	eventPtr->time = milliSec;
496*56814Sralph 	eventPtr->x = fp->fbu->scrInfo.mouse.x;
497*56814Sralph 	eventPtr->y = fp->fbu->scrInfo.mouse.y;
498*56814Sralph 	eventPtr->device = MOUSE_DEVICE;
499*56814Sralph 	fp->fbu->scrInfo.qe.eTail = PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1);
500*56814Sralph 	selwakeup(&fp->selp);
501*56814Sralph }
502*56814Sralph 
503*56814Sralph /*
504*56814Sralph  *----------------------------------------------------------------------
505*56814Sralph  *
506*56814Sralph  * fbMouseButtons --
507*56814Sralph  *
508*56814Sralph  *	Process mouse buttons.
509*56814Sralph  *
510*56814Sralph  * Results:
511*56814Sralph  *	None.
512*56814Sralph  *
513*56814Sralph  * Side effects:
514*56814Sralph  *	None.
515*56814Sralph  *
516*56814Sralph  *----------------------------------------------------------------------
517*56814Sralph  */
518*56814Sralph void
519*56814Sralph fbMouseButtons(newRepPtr, fp)
520*56814Sralph 	MouseReport *newRepPtr;
521*56814Sralph 	register struct pmax_fb *fp;
522*56814Sralph {
523*56814Sralph 	static char temp, oldSwitch, newSwitch;
524*56814Sralph 	int i, j;
525*56814Sralph 	pmEvent *eventPtr;
526*56814Sralph 	static MouseReport lastRep;
527*56814Sralph 
528*56814Sralph 	if (!fp->GraphicsOpen)
529*56814Sralph 		return;
530*56814Sralph 
531*56814Sralph 	newSwitch = newRepPtr->state & 0x07;
532*56814Sralph 	oldSwitch = lastRep.state & 0x07;
533*56814Sralph 
534*56814Sralph 	temp = oldSwitch ^ newSwitch;
535*56814Sralph 	if (temp == 0)
536*56814Sralph 		return;
537*56814Sralph 	for (j = 1; j < 8; j <<= 1) {
538*56814Sralph 		if ((j & temp) == 0)
539*56814Sralph 			continue;
540*56814Sralph 
541*56814Sralph 		/*
542*56814Sralph 		 * Check for room in the queue
543*56814Sralph 		 */
544*56814Sralph 		i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail+1);
545*56814Sralph 		if (i == fp->fbu->scrInfo.qe.eHead)
546*56814Sralph 			return;
547*56814Sralph 
548*56814Sralph 		/*
549*56814Sralph 		 * Put event into queue.
550*56814Sralph 		 */
551*56814Sralph 		eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
552*56814Sralph 
553*56814Sralph 		switch (j) {
554*56814Sralph 		case RIGHT_BUTTON:
555*56814Sralph 			eventPtr->key = EVENT_RIGHT_BUTTON;
556*56814Sralph 			break;
557*56814Sralph 
558*56814Sralph 		case MIDDLE_BUTTON:
559*56814Sralph 			eventPtr->key = EVENT_MIDDLE_BUTTON;
560*56814Sralph 			break;
561*56814Sralph 
562*56814Sralph 		case LEFT_BUTTON:
563*56814Sralph 			eventPtr->key = EVENT_LEFT_BUTTON;
564*56814Sralph 		}
565*56814Sralph 		if (newSwitch & j)
566*56814Sralph 			eventPtr->type = BUTTON_DOWN_TYPE;
567*56814Sralph 		else
568*56814Sralph 			eventPtr->type = BUTTON_UP_TYPE;
569*56814Sralph 		eventPtr->device = MOUSE_DEVICE;
570*56814Sralph 
571*56814Sralph 		eventPtr->time = TO_MS(time);
572*56814Sralph 		eventPtr->x = fp->fbu->scrInfo.mouse.x;
573*56814Sralph 		eventPtr->y = fp->fbu->scrInfo.mouse.y;
574*56814Sralph 	}
575*56814Sralph 	fp->fbu->scrInfo.qe.eTail = i;
576*56814Sralph 	selwakeup(&fp->selp);
577*56814Sralph 
578*56814Sralph 	lastRep = *newRepPtr;
579*56814Sralph 	fp->fbu->scrInfo.mswitches = newSwitch;
580*56814Sralph }
581*56814Sralph 
582*56814Sralph /*
583*56814Sralph  *----------------------------------------------------------------------
584*56814Sralph  *
585*56814Sralph  * fbScroll --
586*56814Sralph  *
587*56814Sralph  *	Scroll the screen.
588*56814Sralph  *
589*56814Sralph  * Results:
590*56814Sralph  *	None.
591*56814Sralph  *
592*56814Sralph  * Side effects:
593*56814Sralph  *	None.
594*56814Sralph  *
595*56814Sralph  *----------------------------------------------------------------------
596*56814Sralph  */
597*56814Sralph void
598*56814Sralph fbScroll(fp)
599*56814Sralph 	register struct pmax_fb *fp;
600*56814Sralph {
601*56814Sralph 	register int *dest, *src;
602*56814Sralph 	register int *end;
603*56814Sralph 	register int temp0, temp1, temp2, temp3;
604*56814Sralph 	register int i, scanInc, lineCount;
605*56814Sralph 	int line;
606*56814Sralph 
607*56814Sralph 	/*
608*56814Sralph 	 * If the mouse is on we don't scroll so that the bit map remains sane.
609*56814Sralph 	 */
610*56814Sralph 	if (fp->GraphicsOpen) {
611*56814Sralph 		fp->row = 0;
612*56814Sralph 		return;
613*56814Sralph 	}
614*56814Sralph 
615*56814Sralph 	/*
616*56814Sralph 	 *  The following is an optimization to cause the scrolling
617*56814Sralph 	 *  of text to be memory limited.  Basically the writebuffer is
618*56814Sralph 	 *  4 words (32 bits ea.) long so to achieve maximum speed we
619*56814Sralph 	 *  read and write in multiples of 4 words. We also limit the
620*56814Sralph 	 *  size to be fp->fbu->scrInfo.max_col characters for more speed.
621*56814Sralph 	 */
622*56814Sralph 	if (fp->isMono) {
623*56814Sralph 		lineCount = 5;
624*56814Sralph 		line = 1920 * 2;
625*56814Sralph 		scanInc = 44;
626*56814Sralph 	} else {
627*56814Sralph 		lineCount = 40;
628*56814Sralph 		scanInc = 96;
629*56814Sralph 		line = 1920 * 8;
630*56814Sralph 	}
631*56814Sralph 	src = (int *)(fp->fr_addr + line);
632*56814Sralph 	dest = (int *)(fp->fr_addr);
633*56814Sralph 	end = (int *)(fp->fr_addr + (60 * line) - line);
634*56814Sralph 	do {
635*56814Sralph 		i = 0;
636*56814Sralph 		do {
637*56814Sralph 			temp0 = src[0];
638*56814Sralph 			temp1 = src[1];
639*56814Sralph 			temp2 = src[2];
640*56814Sralph 			temp3 = src[3];
641*56814Sralph 			dest[0] = temp0;
642*56814Sralph 			dest[1] = temp1;
643*56814Sralph 			dest[2] = temp2;
644*56814Sralph 			dest[3] = temp3;
645*56814Sralph 			dest += 4;
646*56814Sralph 			src += 4;
647*56814Sralph 			i++;
648*56814Sralph 		} while (i < lineCount);
649*56814Sralph 		src += scanInc;
650*56814Sralph 		dest += scanInc;
651*56814Sralph 	} while (src < end);
652*56814Sralph 
653*56814Sralph 	/*
654*56814Sralph 	 * Now zero out the last two lines
655*56814Sralph 	 */
656*56814Sralph 	bzero(fp->fr_addr + (fp->row * line), 3 * line);
657*56814Sralph }
658*56814Sralph 
659*56814Sralph /*
660*56814Sralph  *----------------------------------------------------------------------
661*56814Sralph  *
662*56814Sralph  * fbPutc --
663*56814Sralph  *
664*56814Sralph  *	Write a character to the console.
665*56814Sralph  *
666*56814Sralph  * Results:
667*56814Sralph  *	None.
668*56814Sralph  *
669*56814Sralph  * Side effects:
670*56814Sralph  *	None.
671*56814Sralph  *
672*56814Sralph  *----------------------------------------------------------------------
673*56814Sralph  */
674*56814Sralph void
675*56814Sralph fbPutc(dev, c)
676*56814Sralph 	dev_t dev;
677*56814Sralph 	register int c;
678*56814Sralph {
679*56814Sralph 	int s;
680*56814Sralph 
681*56814Sralph 	if (cn_tab.cn_fb) {
682*56814Sralph 		static int recurse;
683*56814Sralph 
684*56814Sralph 		/*
685*56814Sralph 		 * We need to prevent recursion in case a printf to the
686*56814Sralph 		 * console happens at interrupt time but using splhigh()
687*56814Sralph 		 * all the time locks out interrupts too much. We simply
688*56814Sralph 		 * discard the character in this case and rely on the
689*56814Sralph 		 * console log buffer to save the message.
690*56814Sralph 		 */
691*56814Sralph 		if (recurse)
692*56814Sralph 			return;
693*56814Sralph 		recurse = 1;
694*56814Sralph 		fbBlitc(c, cn_tab.cn_fb);
695*56814Sralph 		recurse = 0;
696*56814Sralph 	} else {
697*56814Sralph 		s = splhigh();
698*56814Sralph 		(*callv->printf)("%c", c);
699*56814Sralph 		splx(s);
700*56814Sralph 	}
701*56814Sralph }
702*56814Sralph 
703*56814Sralph /*
704*56814Sralph  *----------------------------------------------------------------------
705*56814Sralph  *
706*56814Sralph  * fbBlitc --
707*56814Sralph  *
708*56814Sralph  *	Write a character to the screen.
709*56814Sralph  *
710*56814Sralph  * Results:
711*56814Sralph  *	None.
712*56814Sralph  *
713*56814Sralph  * Side effects:
714*56814Sralph  *	None.
715*56814Sralph  *
716*56814Sralph  *----------------------------------------------------------------------
717*56814Sralph  */
718*56814Sralph void
719*56814Sralph fbBlitc(c, fp)
720*56814Sralph 	register int c;
721*56814Sralph 	register struct pmax_fb *fp;
722*56814Sralph {
723*56814Sralph 	register char *bRow, *fRow;
724*56814Sralph 	register int i;
725*56814Sralph 	register int ote = fp->isMono ? 256 : 1024; /* offset to table entry */
726*56814Sralph 	int colMult = fp->isMono ? 1 : 8;
727*56814Sralph 
728*56814Sralph 	c &= 0xff;
729*56814Sralph 
730*56814Sralph 	switch (c) {
731*56814Sralph 	case '\t':
732*56814Sralph 		for (i = 8 - (fp->col & 0x7); i > 0; i--)
733*56814Sralph 			fbBlitc(' ', fp);
734*56814Sralph 		break;
735*56814Sralph 
736*56814Sralph 	case '\r':
737*56814Sralph 		fp->col = 0;
738*56814Sralph 		break;
739*56814Sralph 
740*56814Sralph 	case '\b':
741*56814Sralph 		fp->col--;
742*56814Sralph 		if (fp->col < 0)
743*56814Sralph 			fp->col = 0;
744*56814Sralph 		break;
745*56814Sralph 
746*56814Sralph 	case '\n':
747*56814Sralph 		if (fp->row + 1 >= fp->fbu->scrInfo.max_row)
748*56814Sralph 			fbScroll(fp);
749*56814Sralph 		else
750*56814Sralph 			fp->row++;
751*56814Sralph 		fp->col = 0;
752*56814Sralph 		break;
753*56814Sralph 
754*56814Sralph 	case '\007':
755*56814Sralph 		(*fp->KBDPutc)(fp->kbddev, LK_RING_BELL);
756*56814Sralph 		break;
757*56814Sralph 
758*56814Sralph 	default:
759*56814Sralph 		/*
760*56814Sralph 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
761*56814Sralph 		 * support.
762*56814Sralph 		 */
763*56814Sralph 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
764*56814Sralph 			break;
765*56814Sralph 		/*
766*56814Sralph 		 * If the next character will wrap around then
767*56814Sralph 		 * increment fp->row counter or scroll screen.
768*56814Sralph 		 */
769*56814Sralph 		if (fp->col >= fp->fbu->scrInfo.max_col) {
770*56814Sralph 			fp->col = 0;
771*56814Sralph 			if (fp->row + 1 >= fp->fbu->scrInfo.max_row)
772*56814Sralph 				fbScroll(fp);
773*56814Sralph 			else
774*56814Sralph 				fp->row++;
775*56814Sralph 		}
776*56814Sralph 		bRow = (char *)(fp->fr_addr +
777*56814Sralph 			(fp->row * 15 & 0x3ff) * ote + fp->col * colMult);
778*56814Sralph 		i = c - ' ';
779*56814Sralph 		/*
780*56814Sralph 		 * This is to skip the (32) 8-bit
781*56814Sralph 		 * control chars, as well as DEL
782*56814Sralph 		 * and 0xA0 which aren't printable
783*56814Sralph 		 */
784*56814Sralph 		if (c > '~')
785*56814Sralph 			i -= 34;
786*56814Sralph 		i *= 15;
787*56814Sralph 		fRow = (char *)((int)pmFont + i);
788*56814Sralph 
789*56814Sralph 		/* inline expansion for speed */
790*56814Sralph 		if (fp->isMono) {
791*56814Sralph 			*bRow = *fRow++; bRow += ote;
792*56814Sralph 			*bRow = *fRow++; bRow += ote;
793*56814Sralph 			*bRow = *fRow++; bRow += ote;
794*56814Sralph 			*bRow = *fRow++; bRow += ote;
795*56814Sralph 			*bRow = *fRow++; bRow += ote;
796*56814Sralph 			*bRow = *fRow++; bRow += ote;
797*56814Sralph 			*bRow = *fRow++; bRow += ote;
798*56814Sralph 			*bRow = *fRow++; bRow += ote;
799*56814Sralph 			*bRow = *fRow++; bRow += ote;
800*56814Sralph 			*bRow = *fRow++; bRow += ote;
801*56814Sralph 			*bRow = *fRow++; bRow += ote;
802*56814Sralph 			*bRow = *fRow++; bRow += ote;
803*56814Sralph 			*bRow = *fRow++; bRow += ote;
804*56814Sralph 			*bRow = *fRow++; bRow += ote;
805*56814Sralph 			*bRow = *fRow++; bRow += ote;
806*56814Sralph 		} else {
807*56814Sralph 			register int j;
808*56814Sralph 			register unsigned int *pInt;
809*56814Sralph 
810*56814Sralph 			pInt = (unsigned int *)bRow;
811*56814Sralph 			for (j = 0; j < 15; j++) {
812*56814Sralph 				/*
813*56814Sralph 				 * fontmaskBits converts a nibble
814*56814Sralph 				 * (4 bytes) to a long word
815*56814Sralph 				 * containing 4 pixels corresponding
816*56814Sralph 				 * to each bit in the nibble.  Thus
817*56814Sralph 				 * we write two longwords for each
818*56814Sralph 				 * byte in font.
819*56814Sralph 				 *
820*56814Sralph 				 * Remember the font is 8 bits wide
821*56814Sralph 				 * and 15 bits high.
822*56814Sralph 				 *
823*56814Sralph 				 * We add 256 to the pointer to
824*56814Sralph 				 * point to the pixel on the
825*56814Sralph 				 * next scan line
826*56814Sralph 				 * directly below the current
827*56814Sralph 				 * pixel.
828*56814Sralph 				 */
829*56814Sralph 				pInt[0] = fontmaskBits[(*fRow) & 0xf];
830*56814Sralph 				pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
831*56814Sralph 				fRow++;
832*56814Sralph 				pInt += 256;
833*56814Sralph 			}
834*56814Sralph 		}
835*56814Sralph 		fp->col++; /* increment column counter */
836*56814Sralph 	}
837*56814Sralph 	if (!fp->GraphicsOpen)
838*56814Sralph 		(*fp->posCursor)(fp->col * 8, fp->row * 15);
839*56814Sralph }
840*56814Sralph 
841*56814Sralph /*
842*56814Sralph  * ----------------------------------------------------------------------------
843*56814Sralph  *
844*56814Sralph  * kbdMapChar --
845*56814Sralph  *
846*56814Sralph  *	Map characters from the keyboard to ASCII. Return -1 if there is
847*56814Sralph  *	no valid mapping.
848*56814Sralph  *
849*56814Sralph  * Results:
850*56814Sralph  *	None.
851*56814Sralph  *
852*56814Sralph  * Side effects:
853*56814Sralph  *	Remember state of shift and control keys.
854*56814Sralph  *
855*56814Sralph  * ----------------------------------------------------------------------------
856*56814Sralph  */
857*56814Sralph kbdMapChar(cc)
858*56814Sralph 	int cc;
859*56814Sralph {
860*56814Sralph 	static u_char shiftDown;
861*56814Sralph 	static u_char ctrlDown;
862*56814Sralph 	static u_char lastChar;
863*56814Sralph 
864*56814Sralph 	switch (cc) {
865*56814Sralph 	case KEY_REPEAT:
866*56814Sralph 		cc = lastChar;
867*56814Sralph 		goto done;
868*56814Sralph 
869*56814Sralph 	case KEY_UP:
870*56814Sralph 		shiftDown = 0;
871*56814Sralph 		ctrlDown = 0;
872*56814Sralph 		return (-1);
873*56814Sralph 
874*56814Sralph 	case KEY_SHIFT:
875*56814Sralph 	case KEY_R_SHIFT:
876*56814Sralph 		if (ctrlDown || shiftDown)
877*56814Sralph 			shiftDown = 0;
878*56814Sralph 		else
879*56814Sralph 			shiftDown = 1;
880*56814Sralph 		return (-1);
881*56814Sralph 
882*56814Sralph 	case KEY_CONTROL:
883*56814Sralph 		if (shiftDown || ctrlDown)
884*56814Sralph 			ctrlDown = 0;
885*56814Sralph 		else
886*56814Sralph 			ctrlDown = 1;
887*56814Sralph 		return (-1);
888*56814Sralph 
889*56814Sralph 	case LK_POWER_ERROR:
890*56814Sralph 	case LK_KDOWN_ERROR:
891*56814Sralph 	case LK_INPUT_ERROR:
892*56814Sralph 	case LK_OUTPUT_ERROR:
893*56814Sralph 		log(LOG_WARNING,
894*56814Sralph 			"lk201: keyboard error, code=%x\n", cc);
895*56814Sralph 		return (-1);
896*56814Sralph 	}
897*56814Sralph 	if (shiftDown)
898*56814Sralph 		cc = shiftedAscii[cc];
899*56814Sralph 	else
900*56814Sralph 		cc = unshiftedAscii[cc];
901*56814Sralph 	if (cc >= KBD_NOKEY) {
902*56814Sralph 		/*
903*56814Sralph 		 * A function key was typed - ignore it.
904*56814Sralph 		 */
905*56814Sralph 		return (-1);
906*56814Sralph 	}
907*56814Sralph 	if (cc >= 'a' && cc <= 'z') {
908*56814Sralph 		if (ctrlDown)
909*56814Sralph 			cc = cc - 'a' + '\1'; /* ^A */
910*56814Sralph 		else if (shiftDown)
911*56814Sralph 			cc = cc - 'a' + 'A';
912*56814Sralph 	} else if (ctrlDown) {
913*56814Sralph 		if (cc >= '[' && cc <= '_')
914*56814Sralph 			cc = cc - '@';
915*56814Sralph 		else if (cc == ' ' || cc == '@')
916*56814Sralph 			cc = '\0';
917*56814Sralph 	}
918*56814Sralph 	lastChar = cc;
919*56814Sralph done:
920*56814Sralph 	return (cc);
921*56814Sralph }
922*56814Sralph 
923*56814Sralph /*
924*56814Sralph  * Initialize the Keyboard.
925*56814Sralph  */
926*56814Sralph void
927*56814Sralph KBDReset(kbddev, putc)
928*56814Sralph 	dev_t kbddev;
929*56814Sralph 	void (*putc)();
930*56814Sralph {
931*56814Sralph 	register int i;
932*56814Sralph 	static int inKBDReset;
933*56814Sralph 
934*56814Sralph 	if (inKBDReset)
935*56814Sralph 		return;
936*56814Sralph 	inKBDReset = 1;
937*56814Sralph 	for (i = 0; i < sizeof(kbdInitString); i++)
938*56814Sralph 		(*putc)(kbddev, (int)kbdInitString[i]);
939*56814Sralph 	inKBDReset = 0;
940*56814Sralph }
941*56814Sralph 
942*56814Sralph /*
943*56814Sralph  * Initialize the mouse.
944*56814Sralph  */
945*56814Sralph void
946*56814Sralph MouseInit(mdev, putc, getc)
947*56814Sralph 	dev_t mdev;
948*56814Sralph 	void (*putc)();
949*56814Sralph 	int (*getc)();
950*56814Sralph {
951*56814Sralph 	int id_byte1, id_byte2, id_byte3, id_byte4;
952*56814Sralph 
953*56814Sralph 	/*
954*56814Sralph 	 * Initialize the mouse.
955*56814Sralph 	 */
956*56814Sralph 	(*putc)(mdev, MOUSE_SELF_TEST);
957*56814Sralph 	id_byte1 = (*getc)(mdev);
958*56814Sralph 	if (id_byte1 < 0) {
959*56814Sralph 		printf("MouseInit: Timeout on 1st byte of self-test report\n");
960*56814Sralph 		return;
961*56814Sralph 	}
962*56814Sralph 	id_byte2 = (*getc)(mdev);
963*56814Sralph 	if (id_byte2 < 0) {
964*56814Sralph 		printf("MouseInit: Timeout on 2nd byte of self-test report\n");
965*56814Sralph 		return;
966*56814Sralph 	}
967*56814Sralph 	id_byte3 = (*getc)(mdev);
968*56814Sralph 	if (id_byte3 < 0) {
969*56814Sralph 		printf("MouseInit: Timeout on 3rd byte of self-test report\n");
970*56814Sralph 		return;
971*56814Sralph 	}
972*56814Sralph 	id_byte4 = (*getc)(mdev);
973*56814Sralph 	if (id_byte4 < 0) {
974*56814Sralph 		printf("MouseInit: Timeout on 4th byte of self-test report\n");
975*56814Sralph 		return;
976*56814Sralph 	}
977*56814Sralph 	if ((id_byte2 & 0x0f) != 0x2)
978*56814Sralph 		printf("MouseInit: We don't have a mouse!!!\n");
979*56814Sralph 	/*
980*56814Sralph 	 * For some reason, the mouse doesn't see this command if it comes
981*56814Sralph 	 * too soon after a self test.
982*56814Sralph 	 */
983*56814Sralph 	DELAY(100);
984*56814Sralph 	(*putc)(mdev, MOUSE_INCREMENTAL);
985*56814Sralph }
986*56814Sralph 
987*56814Sralph /*
988*56814Sralph  * Get a character off of the keyboard.
989*56814Sralph  */
990*56814Sralph int
991*56814Sralph KBDGetc()
992*56814Sralph {
993*56814Sralph 	register int c;
994*56814Sralph 
995*56814Sralph 	for (;;) {
996*56814Sralph 		c = (*cn_tab.cn_kbdgetc)(cn_tab.cn_dev);
997*56814Sralph 		if (c == 0)
998*56814Sralph 			return (-1);
999*56814Sralph 		if ((c = kbdMapChar(c & 0xff)) >= 0)
1000*56814Sralph 			break;
1001*56814Sralph 	}
1002*56814Sralph 	return (c);
1003*56814Sralph }
1004