xref: /csrg-svn/sys/pmax/dev/fb.c (revision 57234)
156814Sralph /*-
256814Sralph  * Copyright (c) 1992 The Regents of the University of California.
356814Sralph  * All rights reserved.
456814Sralph  *
556814Sralph  * This code is derived from software contributed to Berkeley by
656814Sralph  * Ralph Campbell and Rick Macklem.
756814Sralph  *
856814Sralph  * %sccs.include.redist.c%
956814Sralph  *
10*57234Sralph  *	@(#)fb.c	7.2 (Berkeley) 12/20/92
1156814Sralph  */
1256814Sralph 
1356814Sralph /*
1456814Sralph  *  devGraphics.c --
1556814Sralph  *
1656814Sralph  *     	This file contains machine-dependent routines for the graphics device.
1756814Sralph  *
1856814Sralph  *	Copyright (C) 1989 Digital Equipment Corporation.
1956814Sralph  *	Permission to use, copy, modify, and distribute this software and
2056814Sralph  *	its documentation for any purpose and without fee is hereby granted,
2156814Sralph  *	provided that the above copyright notice appears in all copies.
2256814Sralph  *	Digital Equipment Corporation makes no representations about the
2356814Sralph  *	suitability of this software for any purpose.  It is provided "as is"
2456814Sralph  *	without express or implied warranty.
2556814Sralph  *
2656814Sralph  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
2756814Sralph  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
2856814Sralph  */
2956814Sralph 
3056814Sralph /*
3156814Sralph  * This file has all the routines common to the various frame buffer drivers
3256814Sralph  * including a generic ioctl routine. The pmax_fb structure is passed into the
3356814Sralph  * routines and has device specifics stored in it.
3456814Sralph  * The LK201 keycode mapping routine is also here along with initialization
3556814Sralph  * functions for the keyboard and mouse.
3656814Sralph  */
3756814Sralph 
3856814Sralph #include <sys/param.h>
3956814Sralph #include <sys/systm.h>
4056814Sralph #include <sys/ioctl.h>
4156814Sralph #include <sys/tty.h>
4256814Sralph #include <sys/time.h>
4356814Sralph #include <sys/kernel.h>
4456814Sralph #include <sys/ioctl.h>
4556814Sralph #include <sys/file.h>
4656814Sralph #include <sys/errno.h>
4756814Sralph #include <sys/proc.h>
4856814Sralph #include <sys/mman.h>
4956814Sralph #include <sys/syslog.h>
5056814Sralph 
5156814Sralph #include <vm/vm.h>
5256814Sralph 
5356814Sralph #include <machine/machConst.h>
5456814Sralph #include <machine/pmioctl.h>
5556814Sralph 
5656814Sralph #include <pmax/dev/device.h>
5756814Sralph #include <pmax/dev/font.c>
5856814Sralph #include <pmax/dev/fbreg.h>
5956814Sralph 
6056814Sralph #include <pmax/stand/dec_prom.h>
6156814Sralph 
6256814Sralph #include <pmax/pmax/cons.h>
6356814Sralph #include <pmax/pmax/pmaxtype.h>
6456814Sralph 
65*57234Sralph #include <dc.h>
66*57234Sralph #include <scc.h>
67*57234Sralph #include <dtop.h>
68*57234Sralph 
6956814Sralph void fbKbdEvent(), fbMouseEvent(), fbMouseButtons(), fbScroll();
7056814Sralph void fbBlitc(), fbPutc();
7156814Sralph extern int pmax_boardtype;
7256814Sralph extern struct consdev cn_tab;
7356814Sralph #if NDC > 0
74*57234Sralph #include <machine/dc7085cons.h>
7556814Sralph extern int dcGetc(), dcparam();
7656814Sralph extern void dcPutc();
7756814Sralph #endif
78*57234Sralph #if NDTOP > 0
79*57234Sralph #include <pmax/dev/dtopreg.h>
80*57234Sralph extern void dtopKBDPutc();
81*57234Sralph #endif
8256814Sralph #if NSCC > 0
83*57234Sralph #include <pmax/dev/sccreg.h>
8456814Sralph extern int sccGetc(), sccparam();
8556814Sralph extern void sccPutc();
8656814Sralph #endif
8756814Sralph 
8856814Sralph /*
8956814Sralph  * The default cursor.
9056814Sralph  */
9156814Sralph u_short defCursor[32] = {
9256814Sralph /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
9356814Sralph 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
9456814Sralph /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
9556814Sralph               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
9656814Sralph 
9756814Sralph };
9856814Sralph 
9956814Sralph /*
10056814Sralph  * Font mask bits used by fbBlitc().
10156814Sralph  */
10256814Sralph static unsigned int fontmaskBits[16] = {
10356814Sralph 	0x00000000,
10456814Sralph 	0x00000001,
10556814Sralph 	0x00000100,
10656814Sralph 	0x00000101,
10756814Sralph 	0x00010000,
10856814Sralph 	0x00010001,
10956814Sralph 	0x00010100,
11056814Sralph 	0x00010101,
11156814Sralph 	0x01000000,
11256814Sralph 	0x01000001,
11356814Sralph 	0x01000100,
11456814Sralph 	0x01000101,
11556814Sralph 	0x01010000,
11656814Sralph 	0x01010001,
11756814Sralph 	0x01010100,
11856814Sralph 	0x01010101
11956814Sralph };
12056814Sralph 
12156814Sralph /*
12256814Sralph  * Ascii values of command keys.
12356814Sralph  */
12456814Sralph #define KBD_TAB		'\t'
12556814Sralph #define KBD_DEL		127
12656814Sralph #define KBD_RET		'\r'
12756814Sralph 
12856814Sralph /*
12956814Sralph  *  Define "hardware-independent" codes for the control, shift, meta and
13056814Sralph  *  function keys.  Codes start after the last 7-bit ASCII code (127)
13156814Sralph  *  and are assigned in an arbitrary order.
13256814Sralph  */
13356814Sralph #define KBD_NOKEY	128
13456814Sralph 
13556814Sralph #define KBD_F1		201
13656814Sralph #define KBD_F2		202
13756814Sralph #define KBD_F3		203
13856814Sralph #define KBD_F4		204
13956814Sralph #define KBD_F5		205
14056814Sralph #define KBD_F6		206
14156814Sralph #define KBD_F7		207
14256814Sralph #define KBD_F8		208
14356814Sralph #define KBD_F9		209
14456814Sralph #define KBD_F10		210
14556814Sralph #define KBD_F11		211
14656814Sralph #define KBD_F12		212
14756814Sralph #define KBD_F13		213
14856814Sralph #define KBD_F14		214
14956814Sralph #define KBD_HELP	215
15056814Sralph #define KBD_DO		216
15156814Sralph #define KBD_F17		217
15256814Sralph #define KBD_F18		218
15356814Sralph #define KBD_F19		219
15456814Sralph #define KBD_F20		220
15556814Sralph 
15656814Sralph #define KBD_FIND	221
15756814Sralph #define KBD_INSERT	222
15856814Sralph #define KBD_REMOVE	223
15956814Sralph #define KBD_SELECT	224
16056814Sralph #define KBD_PREVIOUS	225
16156814Sralph #define KBD_NEXT	226
16256814Sralph 
16356814Sralph #define KBD_KP_ENTER	227
16456814Sralph #define KBD_KP_F1	228
16556814Sralph #define KBD_KP_F2	229
16656814Sralph #define KBD_KP_F3	230
16756814Sralph #define KBD_KP_F4	231
16856814Sralph #define KBD_LEFT	232
16956814Sralph #define KBD_RIGHT	233
17056814Sralph #define KBD_DOWN	234
17156814Sralph #define KBD_UP		235
17256814Sralph 
17356814Sralph #define KBD_CONTROL	236
17456814Sralph #define KBD_SHIFT	237
17556814Sralph #define KBD_CAPSLOCK	238
17656814Sralph #define KBD_ALTERNATE	239
17756814Sralph 
17856814Sralph /*
17956814Sralph  * Keyboard to Ascii, unshifted.
18056814Sralph  */
18156814Sralph static unsigned char unshiftedAscii[] = {
18256814Sralph /*  0 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18356814Sralph /*  4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18456814Sralph /*  8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18556814Sralph /*  c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18656814Sralph /* 10 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18756814Sralph /* 14 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18856814Sralph /* 18 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
18956814Sralph /* 1c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19056814Sralph /* 20 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19156814Sralph /* 24 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19256814Sralph /* 28 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19356814Sralph /* 2c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19456814Sralph /* 30 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19556814Sralph /* 34 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19656814Sralph /* 38 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19756814Sralph /* 3c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19856814Sralph /* 40 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
19956814Sralph /* 44 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20056814Sralph /* 48 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20156814Sralph /* 4c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20256814Sralph /* 50 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20356814Sralph /* 54 */ KBD_NOKEY,	KBD_NOKEY,	KBD_F1,		KBD_F2,
20456814Sralph /* 58 */ KBD_F3,	KBD_F4,		KBD_F5,		KBD_NOKEY,
20556814Sralph /* 5c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20656814Sralph /* 60 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20756814Sralph /* 64 */ KBD_F6,	KBD_F7,		KBD_F8,		KBD_F9,
20856814Sralph /* 68 */ KBD_F10,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
20956814Sralph /* 6c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
21056814Sralph /* 70 */ KBD_NOKEY,	'\033',		KBD_F12,	KBD_F13,
21156814Sralph /* 74 */ KBD_F14,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
21256814Sralph /* 78 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
21356814Sralph /* 7c */ KBD_HELP,	KBD_DO,		KBD_NOKEY,	KBD_NOKEY,
21456814Sralph /* 80 */ KBD_F17,	KBD_F18,	KBD_F19,	KBD_F20,
21556814Sralph /* 84 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
21656814Sralph /* 88 */ KBD_NOKEY,	KBD_NOKEY,	KBD_FIND,	KBD_INSERT,
21756814Sralph /* 8c */ KBD_REMOVE,	KBD_SELECT,	KBD_PREVIOUS,	KBD_NEXT,
21856814Sralph /* 90 */ KBD_NOKEY,	KBD_NOKEY,	'0',		KBD_NOKEY,
21956814Sralph /* 94 */ '.',		KBD_KP_ENTER,	'1',		'2',
22056814Sralph /* 98 */ '3',		'4',		'5',		'6',
22156814Sralph /* 9c */ ',',		'7',		'8',		'9',
22256814Sralph /* a0 */ '-',		KBD_KP_F1,	KBD_KP_F2,	KBD_KP_F3,
22356814Sralph /* a4 */ KBD_KP_F4,	KBD_NOKEY,	KBD_NOKEY,	KBD_LEFT,
22456814Sralph /* a8 */ KBD_RIGHT,	KBD_DOWN, 	KBD_UP,		KBD_NOKEY,
22556814Sralph /* ac */ KBD_NOKEY,	KBD_NOKEY,	KBD_SHIFT,	KBD_CONTROL,
22656814Sralph /* b0 */ KBD_CAPSLOCK,	KBD_ALTERNATE,	KBD_NOKEY,	KBD_NOKEY,
22756814Sralph /* b4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
22856814Sralph /* b8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
22956814Sralph /* bc */ KBD_DEL,	KBD_RET,	KBD_TAB,	'`',
23056814Sralph /* c0 */ '1',		'q',		'a',		'z',
23156814Sralph /* c4 */ KBD_NOKEY,	'2',		'w',		's',
23256814Sralph /* c8 */ 'x',		'<',		KBD_NOKEY,	'3',
23356814Sralph /* cc */ 'e',		'd',		'c',		KBD_NOKEY,
23456814Sralph /* d0 */ '4',		'r',		'f',		'v',
23556814Sralph /* d4 */ ' ',		KBD_NOKEY,	'5',		't',
23656814Sralph /* d8 */ 'g',		'b',		KBD_NOKEY,	'6',
23756814Sralph /* dc */ 'y',		'h',		'n',		KBD_NOKEY,
23856814Sralph /* e0 */ '7',		'u',		'j',		'm',
23956814Sralph /* e4 */ KBD_NOKEY,	'8',		'i',		'k',
24056814Sralph /* e8 */ ',',		KBD_NOKEY,	'9',		'o',
24156814Sralph /* ec */ 'l',		'.',		KBD_NOKEY,	'0',
24256814Sralph /* f0 */ 'p',		KBD_NOKEY,	';',		'/',
24356814Sralph /* f4 */ KBD_NOKEY,	'=',		']',		'\\',
24456814Sralph /* f8 */ KBD_NOKEY,	'-',		'[',		'\'',
24556814Sralph /* fc */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
24656814Sralph };
24756814Sralph 
24856814Sralph /*
24956814Sralph  * Keyboard to Ascii, shifted.
25056814Sralph  */
25156814Sralph static unsigned char shiftedAscii[] = {
25256814Sralph /*  0 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25356814Sralph /*  4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25456814Sralph /*  8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25556814Sralph /*  c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25656814Sralph /* 10 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25756814Sralph /* 14 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25856814Sralph /* 18 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
25956814Sralph /* 1c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26056814Sralph /* 20 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26156814Sralph /* 24 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26256814Sralph /* 28 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26356814Sralph /* 2c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26456814Sralph /* 30 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26556814Sralph /* 34 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26656814Sralph /* 38 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26756814Sralph /* 3c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26856814Sralph /* 40 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
26956814Sralph /* 44 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27056814Sralph /* 48 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27156814Sralph /* 4c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27256814Sralph /* 50 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27356814Sralph /* 54 */ KBD_NOKEY,	KBD_NOKEY,	KBD_F1,		KBD_F2,
27456814Sralph /* 58 */ KBD_F3,	KBD_F4,		KBD_F5,		KBD_NOKEY,
27556814Sralph /* 5c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27656814Sralph /* 60 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27756814Sralph /* 64 */ KBD_F6,	KBD_F7,		KBD_F8,		KBD_F9,
27856814Sralph /* 68 */ KBD_F10,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
27956814Sralph /* 6c */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
28056814Sralph /* 70 */ KBD_NOKEY,	KBD_F11,	KBD_F12,	KBD_F13,
28156814Sralph /* 74 */ KBD_F14,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
28256814Sralph /* 78 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
28356814Sralph /* 7c */ KBD_HELP,	KBD_DO,		KBD_NOKEY,	KBD_NOKEY,
28456814Sralph /* 80 */ KBD_F17,	KBD_F18,	KBD_F19,	KBD_F20,
28556814Sralph /* 84 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
28656814Sralph /* 88 */ KBD_NOKEY,	KBD_NOKEY,	KBD_FIND,	KBD_INSERT,
28756814Sralph /* 8c */ KBD_REMOVE,	KBD_SELECT,	KBD_PREVIOUS,	KBD_NEXT,
28856814Sralph /* 90 */ KBD_NOKEY,	KBD_NOKEY,	'0',		KBD_NOKEY,
28956814Sralph /* 94 */ '.',		KBD_KP_ENTER,	'1',		'2',
29056814Sralph /* 98 */ '3',		'4',		'5',		'6',
29156814Sralph /* 9c */ ',',		'7',		'8',		'9',
29256814Sralph /* a0 */ '-',		KBD_KP_F1,	KBD_KP_F2,	KBD_KP_F3,
29356814Sralph /* a4 */ KBD_KP_F4,	KBD_NOKEY,	KBD_NOKEY,	KBD_LEFT,
29456814Sralph /* a8 */ KBD_RIGHT,	KBD_DOWN, 	KBD_UP,		KBD_NOKEY,
29556814Sralph /* ac */ KBD_NOKEY,	KBD_NOKEY,	KBD_SHIFT,	KBD_CONTROL,
29656814Sralph /* b0 */ KBD_CAPSLOCK,	KBD_ALTERNATE,	KBD_NOKEY,	KBD_NOKEY,
29756814Sralph /* b4 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
29856814Sralph /* b8 */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
29956814Sralph /* bc */ KBD_DEL,	KBD_RET,	KBD_TAB,	'~',
30056814Sralph /* c0 */ '!',		'q',		'a',		'z',
30156814Sralph /* c4 */ KBD_NOKEY,	'@',		'w',		's',
30256814Sralph /* c8 */ 'x',		'>',		KBD_NOKEY,	'#',
30356814Sralph /* cc */ 'e',		'd',		'c',		KBD_NOKEY,
30456814Sralph /* d0 */ '$',		'r',		'f',		'v',
30556814Sralph /* d4 */ ' ',		KBD_NOKEY,	'%',		't',
30656814Sralph /* d8 */ 'g',		'b',		KBD_NOKEY,	'^',
30756814Sralph /* dc */ 'y',		'h',		'n',		KBD_NOKEY,
30856814Sralph /* e0 */ '&',		'u',		'j',		'm',
30956814Sralph /* e4 */ KBD_NOKEY,	'*',		'i',		'k',
31056814Sralph /* e8 */ '<',		KBD_NOKEY,	'(',		'o',
31156814Sralph /* ec */ 'l',		'>',		KBD_NOKEY,	')',
31256814Sralph /* f0 */ 'p',		KBD_NOKEY,	':',		'?',
31356814Sralph /* f4 */ KBD_NOKEY,	'+',		'}',		'|',
31456814Sralph /* f8 */ KBD_NOKEY,	'_',		'{',		'"',
31556814Sralph /* fc */ KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,	KBD_NOKEY,
31656814Sralph };
31756814Sralph 
31856814Sralph /*
31956814Sralph  * Keyboard initialization string.
32056814Sralph  */
32156814Sralph static u_char kbdInitString[] = {
32256814Sralph 	LK_LED_ENABLE, LED_ALL,		/* show we are resetting keyboard */
32356814Sralph 	LK_DEFAULTS,
32456814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 1),
32556814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 2),
32656814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 3),
32756814Sralph 	LK_CMD_MODE(LK_DOWN, 4),	/* could also be LK_AUTODOWN */
32856814Sralph 	LK_CMD_MODE(LK_UPDOWN, 5),
32956814Sralph 	LK_CMD_MODE(LK_UPDOWN, 6),
33056814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 7),
33156814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 8),
33256814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 9),
33356814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 10),
33456814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 11),
33556814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 12),
33656814Sralph 	LK_CMD_MODE(LK_DOWN, 13),
33756814Sralph 	LK_CMD_MODE(LK_AUTODOWN, 14),
33856814Sralph 	LK_AR_ENABLE,			/* we want autorepeat by default */
33956814Sralph 	LK_CL_ENABLE, 0x83,		/* keyclick, volume */
34056814Sralph 	LK_KBD_ENABLE,			/* the keyboard itself */
34156814Sralph 	LK_BELL_ENABLE, 0x83,		/* keyboard bell, volume */
34256814Sralph 	LK_LED_DISABLE, LED_ALL,	/* clear keyboard leds */
34356814Sralph };
34456814Sralph 
34556814Sralph /*
34656814Sralph  *----------------------------------------------------------------------
34756814Sralph  *
34856814Sralph  * fbKbdEvent --
34956814Sralph  *
35056814Sralph  *	Process a received character.
35156814Sralph  *
35256814Sralph  * Results:
35356814Sralph  *	None.
35456814Sralph  *
35556814Sralph  * Side effects:
35656814Sralph  *	Events added to the queue.
35756814Sralph  *
35856814Sralph  *----------------------------------------------------------------------
35956814Sralph  */
36056814Sralph void
36156814Sralph fbKbdEvent(ch, fp)
36256814Sralph 	int ch;
36356814Sralph 	register struct pmax_fb *fp;
36456814Sralph {
36556814Sralph 	register pmEvent *eventPtr;
36656814Sralph 	int i;
36756814Sralph 
36856814Sralph 	if (!fp->GraphicsOpen)
36956814Sralph 		return;
37056814Sralph 
37156814Sralph 	/*
37256814Sralph 	 * See if there is room in the queue.
37356814Sralph 	 */
37456814Sralph 	i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1);
37556814Sralph 	if (i == fp->fbu->scrInfo.qe.eHead)
37656814Sralph 		return;
37756814Sralph 
37856814Sralph 	/*
37956814Sralph 	 * Add the event to the queue.
38056814Sralph 	 */
38156814Sralph 	eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
38256814Sralph 	eventPtr->type = BUTTON_RAW_TYPE;
38356814Sralph 	eventPtr->device = KEYBOARD_DEVICE;
38456814Sralph 	eventPtr->x = fp->fbu->scrInfo.mouse.x;
38556814Sralph 	eventPtr->y = fp->fbu->scrInfo.mouse.y;
38656814Sralph 	eventPtr->time = TO_MS(time);
38756814Sralph 	eventPtr->key = ch;
38856814Sralph 	fp->fbu->scrInfo.qe.eTail = i;
38956814Sralph 	selwakeup(&fp->selp);
39056814Sralph }
39156814Sralph 
39256814Sralph /*
39356814Sralph  *----------------------------------------------------------------------
39456814Sralph  *
39556814Sralph  * fbMouseEvent --
39656814Sralph  *
39756814Sralph  *	Process a mouse event.
39856814Sralph  *
39956814Sralph  * Results:
40056814Sralph  *	None.
40156814Sralph  *
40256814Sralph  * Side effects:
40356814Sralph  *	An event is added to the event queue.
40456814Sralph  *
40556814Sralph  *----------------------------------------------------------------------
40656814Sralph  */
40756814Sralph void
40856814Sralph fbMouseEvent(newRepPtr, fp)
40956814Sralph 	register MouseReport *newRepPtr;
41056814Sralph 	register struct pmax_fb *fp;
41156814Sralph {
41256814Sralph 	unsigned milliSec;
41356814Sralph 	int i;
41456814Sralph 	pmEvent *eventPtr;
41556814Sralph 
41656814Sralph 	if (!fp->GraphicsOpen)
41756814Sralph 		return;
41856814Sralph 
41956814Sralph 	milliSec = TO_MS(time);
42056814Sralph 
42156814Sralph 	/*
42256814Sralph 	 * Check to see if we have to accelerate the mouse
42356814Sralph 	 */
42456814Sralph 	if (fp->fbu->scrInfo.mscale >= 0) {
42556814Sralph 		if (newRepPtr->dx >= fp->fbu->scrInfo.mthreshold) {
42656814Sralph 			newRepPtr->dx +=
42756814Sralph 				(newRepPtr->dx - fp->fbu->scrInfo.mthreshold) *
42856814Sralph 				fp->fbu->scrInfo.mscale;
42956814Sralph 		}
43056814Sralph 		if (newRepPtr->dy >= fp->fbu->scrInfo.mthreshold) {
43156814Sralph 			newRepPtr->dy +=
43256814Sralph 				(newRepPtr->dy - fp->fbu->scrInfo.mthreshold) *
43356814Sralph 				fp->fbu->scrInfo.mscale;
43456814Sralph 		}
43556814Sralph 	}
43656814Sralph 
43756814Sralph 	/*
43856814Sralph 	 * Update mouse position
43956814Sralph 	 */
44056814Sralph 	if (newRepPtr->state & MOUSE_X_SIGN) {
44156814Sralph 		fp->fbu->scrInfo.mouse.x += newRepPtr->dx;
44256814Sralph 		if (fp->fbu->scrInfo.mouse.x > fp->fbu->scrInfo.max_cur_x)
44356814Sralph 			fp->fbu->scrInfo.mouse.x = fp->fbu->scrInfo.max_cur_x;
44456814Sralph 	} else {
44556814Sralph 		fp->fbu->scrInfo.mouse.x -= newRepPtr->dx;
44656814Sralph 		if (fp->fbu->scrInfo.mouse.x < fp->fbu->scrInfo.min_cur_x)
44756814Sralph 			fp->fbu->scrInfo.mouse.x = fp->fbu->scrInfo.min_cur_x;
44856814Sralph 	}
44956814Sralph 	if (newRepPtr->state & MOUSE_Y_SIGN) {
45056814Sralph 		fp->fbu->scrInfo.mouse.y -= newRepPtr->dy;
45156814Sralph 		if (fp->fbu->scrInfo.mouse.y < fp->fbu->scrInfo.min_cur_y)
45256814Sralph 			fp->fbu->scrInfo.mouse.y = fp->fbu->scrInfo.min_cur_y;
45356814Sralph 	} else {
45456814Sralph 		fp->fbu->scrInfo.mouse.y += newRepPtr->dy;
45556814Sralph 		if (fp->fbu->scrInfo.mouse.y > fp->fbu->scrInfo.max_cur_y)
45656814Sralph 			fp->fbu->scrInfo.mouse.y = fp->fbu->scrInfo.max_cur_y;
45756814Sralph 	}
45856814Sralph 
45956814Sralph 	/*
46056814Sralph 	 * Move the hardware cursor.
46156814Sralph 	 */
46256814Sralph 	(*fp->posCursor)(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
46356814Sralph 
46456814Sralph 	/*
46556814Sralph 	 * Store the motion event in the motion buffer.
46656814Sralph 	 */
46756814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].time = milliSec;
46856814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].x = fp->fbu->scrInfo.mouse.x;
46956814Sralph 	fp->fbu->tcs[fp->fbu->scrInfo.qe.tcNext].y = fp->fbu->scrInfo.mouse.y;
47056814Sralph 	if (++fp->fbu->scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
47156814Sralph 		fp->fbu->scrInfo.qe.tcNext = 0;
47256814Sralph 	if (fp->fbu->scrInfo.mouse.y < fp->fbu->scrInfo.mbox.bottom &&
47356814Sralph 	    fp->fbu->scrInfo.mouse.y >=  fp->fbu->scrInfo.mbox.top &&
47456814Sralph 	    fp->fbu->scrInfo.mouse.x < fp->fbu->scrInfo.mbox.right &&
47556814Sralph 	    fp->fbu->scrInfo.mouse.x >=  fp->fbu->scrInfo.mbox.left)
47656814Sralph 		return;
47756814Sralph 
47856814Sralph 	fp->fbu->scrInfo.mbox.bottom = 0;
47956814Sralph 	if (PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1) == fp->fbu->scrInfo.qe.eHead)
48056814Sralph 		return;
48156814Sralph 
48256814Sralph 	i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail - 1);
48356814Sralph 	if ((fp->fbu->scrInfo.qe.eTail != fp->fbu->scrInfo.qe.eHead) &&
48456814Sralph 	    (i != fp->fbu->scrInfo.qe.eHead)) {
48556814Sralph 		pmEvent *eventPtr;
48656814Sralph 
48756814Sralph 		eventPtr = &fp->fbu->events[i];
48856814Sralph 		if (eventPtr->type == MOTION_TYPE) {
48956814Sralph 			eventPtr->x = fp->fbu->scrInfo.mouse.x;
49056814Sralph 			eventPtr->y = fp->fbu->scrInfo.mouse.y;
49156814Sralph 			eventPtr->time = milliSec;
49256814Sralph 			eventPtr->device = MOUSE_DEVICE;
49356814Sralph 			return;
49456814Sralph 		}
49556814Sralph 	}
49656814Sralph 	/*
49756814Sralph 	 * Put event into queue and wakeup any waiters.
49856814Sralph 	 */
49956814Sralph 	eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
50056814Sralph 	eventPtr->type = MOTION_TYPE;
50156814Sralph 	eventPtr->time = milliSec;
50256814Sralph 	eventPtr->x = fp->fbu->scrInfo.mouse.x;
50356814Sralph 	eventPtr->y = fp->fbu->scrInfo.mouse.y;
50456814Sralph 	eventPtr->device = MOUSE_DEVICE;
50556814Sralph 	fp->fbu->scrInfo.qe.eTail = PM_EVROUND(fp->fbu->scrInfo.qe.eTail + 1);
50656814Sralph 	selwakeup(&fp->selp);
50756814Sralph }
50856814Sralph 
50956814Sralph /*
51056814Sralph  *----------------------------------------------------------------------
51156814Sralph  *
51256814Sralph  * fbMouseButtons --
51356814Sralph  *
51456814Sralph  *	Process mouse buttons.
51556814Sralph  *
51656814Sralph  * Results:
51756814Sralph  *	None.
51856814Sralph  *
51956814Sralph  * Side effects:
52056814Sralph  *	None.
52156814Sralph  *
52256814Sralph  *----------------------------------------------------------------------
52356814Sralph  */
52456814Sralph void
52556814Sralph fbMouseButtons(newRepPtr, fp)
52656814Sralph 	MouseReport *newRepPtr;
52756814Sralph 	register struct pmax_fb *fp;
52856814Sralph {
52956814Sralph 	static char temp, oldSwitch, newSwitch;
53056814Sralph 	int i, j;
53156814Sralph 	pmEvent *eventPtr;
53256814Sralph 	static MouseReport lastRep;
53356814Sralph 
53456814Sralph 	if (!fp->GraphicsOpen)
53556814Sralph 		return;
53656814Sralph 
53756814Sralph 	newSwitch = newRepPtr->state & 0x07;
53856814Sralph 	oldSwitch = lastRep.state & 0x07;
53956814Sralph 
54056814Sralph 	temp = oldSwitch ^ newSwitch;
54156814Sralph 	if (temp == 0)
54256814Sralph 		return;
54356814Sralph 	for (j = 1; j < 8; j <<= 1) {
54456814Sralph 		if ((j & temp) == 0)
54556814Sralph 			continue;
54656814Sralph 
54756814Sralph 		/*
54856814Sralph 		 * Check for room in the queue
54956814Sralph 		 */
55056814Sralph 		i = PM_EVROUND(fp->fbu->scrInfo.qe.eTail+1);
55156814Sralph 		if (i == fp->fbu->scrInfo.qe.eHead)
55256814Sralph 			return;
55356814Sralph 
55456814Sralph 		/*
55556814Sralph 		 * Put event into queue.
55656814Sralph 		 */
55756814Sralph 		eventPtr = &fp->fbu->events[fp->fbu->scrInfo.qe.eTail];
55856814Sralph 
55956814Sralph 		switch (j) {
56056814Sralph 		case RIGHT_BUTTON:
56156814Sralph 			eventPtr->key = EVENT_RIGHT_BUTTON;
56256814Sralph 			break;
56356814Sralph 
56456814Sralph 		case MIDDLE_BUTTON:
56556814Sralph 			eventPtr->key = EVENT_MIDDLE_BUTTON;
56656814Sralph 			break;
56756814Sralph 
56856814Sralph 		case LEFT_BUTTON:
56956814Sralph 			eventPtr->key = EVENT_LEFT_BUTTON;
57056814Sralph 		}
57156814Sralph 		if (newSwitch & j)
57256814Sralph 			eventPtr->type = BUTTON_DOWN_TYPE;
57356814Sralph 		else
57456814Sralph 			eventPtr->type = BUTTON_UP_TYPE;
57556814Sralph 		eventPtr->device = MOUSE_DEVICE;
57656814Sralph 
57756814Sralph 		eventPtr->time = TO_MS(time);
57856814Sralph 		eventPtr->x = fp->fbu->scrInfo.mouse.x;
57956814Sralph 		eventPtr->y = fp->fbu->scrInfo.mouse.y;
580*57234Sralph 		fp->fbu->scrInfo.qe.eTail = i;
58156814Sralph 	}
58256814Sralph 	selwakeup(&fp->selp);
58356814Sralph 
58456814Sralph 	lastRep = *newRepPtr;
58556814Sralph 	fp->fbu->scrInfo.mswitches = newSwitch;
58656814Sralph }
58756814Sralph 
58856814Sralph /*
58956814Sralph  *----------------------------------------------------------------------
59056814Sralph  *
59156814Sralph  * fbScroll --
59256814Sralph  *
59356814Sralph  *	Scroll the screen.
59456814Sralph  *
59556814Sralph  * Results:
59656814Sralph  *	None.
59756814Sralph  *
59856814Sralph  * Side effects:
59956814Sralph  *	None.
60056814Sralph  *
60156814Sralph  *----------------------------------------------------------------------
60256814Sralph  */
60356814Sralph void
60456814Sralph fbScroll(fp)
60556814Sralph 	register struct pmax_fb *fp;
60656814Sralph {
60756814Sralph 	register int *dest, *src;
60856814Sralph 	register int *end;
60956814Sralph 	register int temp0, temp1, temp2, temp3;
61056814Sralph 	register int i, scanInc, lineCount;
61156814Sralph 	int line;
61256814Sralph 
61356814Sralph 	/*
61456814Sralph 	 * If the mouse is on we don't scroll so that the bit map remains sane.
61556814Sralph 	 */
61656814Sralph 	if (fp->GraphicsOpen) {
61756814Sralph 		fp->row = 0;
61856814Sralph 		return;
61956814Sralph 	}
62056814Sralph 
62156814Sralph 	/*
62256814Sralph 	 *  The following is an optimization to cause the scrolling
62356814Sralph 	 *  of text to be memory limited.  Basically the writebuffer is
62456814Sralph 	 *  4 words (32 bits ea.) long so to achieve maximum speed we
62556814Sralph 	 *  read and write in multiples of 4 words. We also limit the
62656814Sralph 	 *  size to be fp->fbu->scrInfo.max_col characters for more speed.
62756814Sralph 	 */
62856814Sralph 	if (fp->isMono) {
62956814Sralph 		lineCount = 5;
63056814Sralph 		line = 1920 * 2;
63156814Sralph 		scanInc = 44;
63256814Sralph 	} else {
63356814Sralph 		lineCount = 40;
63456814Sralph 		scanInc = 96;
63556814Sralph 		line = 1920 * 8;
63656814Sralph 	}
63756814Sralph 	src = (int *)(fp->fr_addr + line);
63856814Sralph 	dest = (int *)(fp->fr_addr);
63956814Sralph 	end = (int *)(fp->fr_addr + (60 * line) - line);
64056814Sralph 	do {
64156814Sralph 		i = 0;
64256814Sralph 		do {
64356814Sralph 			temp0 = src[0];
64456814Sralph 			temp1 = src[1];
64556814Sralph 			temp2 = src[2];
64656814Sralph 			temp3 = src[3];
64756814Sralph 			dest[0] = temp0;
64856814Sralph 			dest[1] = temp1;
64956814Sralph 			dest[2] = temp2;
65056814Sralph 			dest[3] = temp3;
65156814Sralph 			dest += 4;
65256814Sralph 			src += 4;
65356814Sralph 			i++;
65456814Sralph 		} while (i < lineCount);
65556814Sralph 		src += scanInc;
65656814Sralph 		dest += scanInc;
65756814Sralph 	} while (src < end);
65856814Sralph 
65956814Sralph 	/*
66056814Sralph 	 * Now zero out the last two lines
66156814Sralph 	 */
66256814Sralph 	bzero(fp->fr_addr + (fp->row * line), 3 * line);
66356814Sralph }
66456814Sralph 
66556814Sralph /*
66656814Sralph  *----------------------------------------------------------------------
66756814Sralph  *
66856814Sralph  * fbPutc --
66956814Sralph  *
67056814Sralph  *	Write a character to the console.
67156814Sralph  *
67256814Sralph  * Results:
67356814Sralph  *	None.
67456814Sralph  *
67556814Sralph  * Side effects:
67656814Sralph  *	None.
67756814Sralph  *
67856814Sralph  *----------------------------------------------------------------------
67956814Sralph  */
68056814Sralph void
68156814Sralph fbPutc(dev, c)
68256814Sralph 	dev_t dev;
68356814Sralph 	register int c;
68456814Sralph {
68556814Sralph 	int s;
68656814Sralph 
68756814Sralph 	if (cn_tab.cn_fb) {
68856814Sralph 		static int recurse;
68956814Sralph 
69056814Sralph 		/*
69156814Sralph 		 * We need to prevent recursion in case a printf to the
69256814Sralph 		 * console happens at interrupt time but using splhigh()
69356814Sralph 		 * all the time locks out interrupts too much. We simply
69456814Sralph 		 * discard the character in this case and rely on the
69556814Sralph 		 * console log buffer to save the message.
69656814Sralph 		 */
69756814Sralph 		if (recurse)
69856814Sralph 			return;
69956814Sralph 		recurse = 1;
70056814Sralph 		fbBlitc(c, cn_tab.cn_fb);
70156814Sralph 		recurse = 0;
70256814Sralph 	} else {
70356814Sralph 		s = splhigh();
70456814Sralph 		(*callv->printf)("%c", c);
70556814Sralph 		splx(s);
70656814Sralph 	}
70756814Sralph }
70856814Sralph 
70956814Sralph /*
71056814Sralph  *----------------------------------------------------------------------
71156814Sralph  *
71256814Sralph  * fbBlitc --
71356814Sralph  *
71456814Sralph  *	Write a character to the screen.
71556814Sralph  *
71656814Sralph  * Results:
71756814Sralph  *	None.
71856814Sralph  *
71956814Sralph  * Side effects:
72056814Sralph  *	None.
72156814Sralph  *
72256814Sralph  *----------------------------------------------------------------------
72356814Sralph  */
72456814Sralph void
72556814Sralph fbBlitc(c, fp)
72656814Sralph 	register int c;
72756814Sralph 	register struct pmax_fb *fp;
72856814Sralph {
72956814Sralph 	register char *bRow, *fRow;
73056814Sralph 	register int i;
73156814Sralph 	register int ote = fp->isMono ? 256 : 1024; /* offset to table entry */
73256814Sralph 	int colMult = fp->isMono ? 1 : 8;
73356814Sralph 
73456814Sralph 	c &= 0xff;
73556814Sralph 
73656814Sralph 	switch (c) {
73756814Sralph 	case '\t':
73856814Sralph 		for (i = 8 - (fp->col & 0x7); i > 0; i--)
73956814Sralph 			fbBlitc(' ', fp);
74056814Sralph 		break;
74156814Sralph 
74256814Sralph 	case '\r':
74356814Sralph 		fp->col = 0;
74456814Sralph 		break;
74556814Sralph 
74656814Sralph 	case '\b':
74756814Sralph 		fp->col--;
74856814Sralph 		if (fp->col < 0)
74956814Sralph 			fp->col = 0;
75056814Sralph 		break;
75156814Sralph 
75256814Sralph 	case '\n':
75356814Sralph 		if (fp->row + 1 >= fp->fbu->scrInfo.max_row)
75456814Sralph 			fbScroll(fp);
75556814Sralph 		else
75656814Sralph 			fp->row++;
75756814Sralph 		fp->col = 0;
75856814Sralph 		break;
75956814Sralph 
76056814Sralph 	case '\007':
76156814Sralph 		(*fp->KBDPutc)(fp->kbddev, LK_RING_BELL);
76256814Sralph 		break;
76356814Sralph 
76456814Sralph 	default:
76556814Sralph 		/*
76656814Sralph 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
76756814Sralph 		 * support.
76856814Sralph 		 */
76956814Sralph 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
77056814Sralph 			break;
77156814Sralph 		/*
77256814Sralph 		 * If the next character will wrap around then
77356814Sralph 		 * increment fp->row counter or scroll screen.
77456814Sralph 		 */
77556814Sralph 		if (fp->col >= fp->fbu->scrInfo.max_col) {
77656814Sralph 			fp->col = 0;
77756814Sralph 			if (fp->row + 1 >= fp->fbu->scrInfo.max_row)
77856814Sralph 				fbScroll(fp);
77956814Sralph 			else
78056814Sralph 				fp->row++;
78156814Sralph 		}
78256814Sralph 		bRow = (char *)(fp->fr_addr +
78356814Sralph 			(fp->row * 15 & 0x3ff) * ote + fp->col * colMult);
78456814Sralph 		i = c - ' ';
78556814Sralph 		/*
78656814Sralph 		 * This is to skip the (32) 8-bit
78756814Sralph 		 * control chars, as well as DEL
78856814Sralph 		 * and 0xA0 which aren't printable
78956814Sralph 		 */
79056814Sralph 		if (c > '~')
79156814Sralph 			i -= 34;
79256814Sralph 		i *= 15;
79356814Sralph 		fRow = (char *)((int)pmFont + i);
79456814Sralph 
79556814Sralph 		/* inline expansion for speed */
79656814Sralph 		if (fp->isMono) {
79756814Sralph 			*bRow = *fRow++; bRow += ote;
79856814Sralph 			*bRow = *fRow++; bRow += ote;
79956814Sralph 			*bRow = *fRow++; bRow += ote;
80056814Sralph 			*bRow = *fRow++; bRow += ote;
80156814Sralph 			*bRow = *fRow++; bRow += ote;
80256814Sralph 			*bRow = *fRow++; bRow += ote;
80356814Sralph 			*bRow = *fRow++; bRow += ote;
80456814Sralph 			*bRow = *fRow++; bRow += ote;
80556814Sralph 			*bRow = *fRow++; bRow += ote;
80656814Sralph 			*bRow = *fRow++; bRow += ote;
80756814Sralph 			*bRow = *fRow++; bRow += ote;
80856814Sralph 			*bRow = *fRow++; bRow += ote;
80956814Sralph 			*bRow = *fRow++; bRow += ote;
81056814Sralph 			*bRow = *fRow++; bRow += ote;
81156814Sralph 			*bRow = *fRow++; bRow += ote;
81256814Sralph 		} else {
81356814Sralph 			register int j;
81456814Sralph 			register unsigned int *pInt;
81556814Sralph 
81656814Sralph 			pInt = (unsigned int *)bRow;
81756814Sralph 			for (j = 0; j < 15; j++) {
81856814Sralph 				/*
81956814Sralph 				 * fontmaskBits converts a nibble
82056814Sralph 				 * (4 bytes) to a long word
82156814Sralph 				 * containing 4 pixels corresponding
82256814Sralph 				 * to each bit in the nibble.  Thus
82356814Sralph 				 * we write two longwords for each
82456814Sralph 				 * byte in font.
82556814Sralph 				 *
82656814Sralph 				 * Remember the font is 8 bits wide
82756814Sralph 				 * and 15 bits high.
82856814Sralph 				 *
82956814Sralph 				 * We add 256 to the pointer to
83056814Sralph 				 * point to the pixel on the
83156814Sralph 				 * next scan line
83256814Sralph 				 * directly below the current
83356814Sralph 				 * pixel.
83456814Sralph 				 */
83556814Sralph 				pInt[0] = fontmaskBits[(*fRow) & 0xf];
83656814Sralph 				pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
83756814Sralph 				fRow++;
83856814Sralph 				pInt += 256;
83956814Sralph 			}
84056814Sralph 		}
84156814Sralph 		fp->col++; /* increment column counter */
84256814Sralph 	}
84356814Sralph 	if (!fp->GraphicsOpen)
84456814Sralph 		(*fp->posCursor)(fp->col * 8, fp->row * 15);
84556814Sralph }
84656814Sralph 
84756814Sralph /*
84856814Sralph  * ----------------------------------------------------------------------------
84956814Sralph  *
85056814Sralph  * kbdMapChar --
85156814Sralph  *
85256814Sralph  *	Map characters from the keyboard to ASCII. Return -1 if there is
85356814Sralph  *	no valid mapping.
85456814Sralph  *
85556814Sralph  * Results:
85656814Sralph  *	None.
85756814Sralph  *
85856814Sralph  * Side effects:
85956814Sralph  *	Remember state of shift and control keys.
86056814Sralph  *
86156814Sralph  * ----------------------------------------------------------------------------
86256814Sralph  */
86356814Sralph kbdMapChar(cc)
86456814Sralph 	int cc;
86556814Sralph {
86656814Sralph 	static u_char shiftDown;
86756814Sralph 	static u_char ctrlDown;
86856814Sralph 	static u_char lastChar;
86956814Sralph 
87056814Sralph 	switch (cc) {
87156814Sralph 	case KEY_REPEAT:
87256814Sralph 		cc = lastChar;
87356814Sralph 		goto done;
87456814Sralph 
87556814Sralph 	case KEY_UP:
87656814Sralph 		shiftDown = 0;
87756814Sralph 		ctrlDown = 0;
87856814Sralph 		return (-1);
87956814Sralph 
88056814Sralph 	case KEY_SHIFT:
88156814Sralph 	case KEY_R_SHIFT:
88256814Sralph 		if (ctrlDown || shiftDown)
88356814Sralph 			shiftDown = 0;
88456814Sralph 		else
88556814Sralph 			shiftDown = 1;
88656814Sralph 		return (-1);
88756814Sralph 
88856814Sralph 	case KEY_CONTROL:
88956814Sralph 		if (shiftDown || ctrlDown)
89056814Sralph 			ctrlDown = 0;
89156814Sralph 		else
89256814Sralph 			ctrlDown = 1;
89356814Sralph 		return (-1);
89456814Sralph 
89556814Sralph 	case LK_POWER_ERROR:
89656814Sralph 	case LK_KDOWN_ERROR:
89756814Sralph 	case LK_INPUT_ERROR:
89856814Sralph 	case LK_OUTPUT_ERROR:
89956814Sralph 		log(LOG_WARNING,
90056814Sralph 			"lk201: keyboard error, code=%x\n", cc);
90156814Sralph 		return (-1);
90256814Sralph 	}
90356814Sralph 	if (shiftDown)
90456814Sralph 		cc = shiftedAscii[cc];
90556814Sralph 	else
90656814Sralph 		cc = unshiftedAscii[cc];
90756814Sralph 	if (cc >= KBD_NOKEY) {
90856814Sralph 		/*
90956814Sralph 		 * A function key was typed - ignore it.
91056814Sralph 		 */
91156814Sralph 		return (-1);
91256814Sralph 	}
91356814Sralph 	if (cc >= 'a' && cc <= 'z') {
91456814Sralph 		if (ctrlDown)
91556814Sralph 			cc = cc - 'a' + '\1'; /* ^A */
91656814Sralph 		else if (shiftDown)
91756814Sralph 			cc = cc - 'a' + 'A';
91856814Sralph 	} else if (ctrlDown) {
91956814Sralph 		if (cc >= '[' && cc <= '_')
92056814Sralph 			cc = cc - '@';
92156814Sralph 		else if (cc == ' ' || cc == '@')
92256814Sralph 			cc = '\0';
92356814Sralph 	}
92456814Sralph 	lastChar = cc;
92556814Sralph done:
92656814Sralph 	return (cc);
92756814Sralph }
92856814Sralph 
92956814Sralph /*
93056814Sralph  * Initialize the Keyboard.
93156814Sralph  */
93256814Sralph void
93356814Sralph KBDReset(kbddev, putc)
93456814Sralph 	dev_t kbddev;
93556814Sralph 	void (*putc)();
93656814Sralph {
93756814Sralph 	register int i;
93856814Sralph 	static int inKBDReset;
93956814Sralph 
94056814Sralph 	if (inKBDReset)
94156814Sralph 		return;
94256814Sralph 	inKBDReset = 1;
94356814Sralph 	for (i = 0; i < sizeof(kbdInitString); i++)
94456814Sralph 		(*putc)(kbddev, (int)kbdInitString[i]);
94556814Sralph 	inKBDReset = 0;
94656814Sralph }
94756814Sralph 
94856814Sralph /*
94956814Sralph  * Initialize the mouse.
95056814Sralph  */
95156814Sralph void
95256814Sralph MouseInit(mdev, putc, getc)
95356814Sralph 	dev_t mdev;
95456814Sralph 	void (*putc)();
95556814Sralph 	int (*getc)();
95656814Sralph {
95756814Sralph 	int id_byte1, id_byte2, id_byte3, id_byte4;
95856814Sralph 
95956814Sralph 	/*
96056814Sralph 	 * Initialize the mouse.
96156814Sralph 	 */
96256814Sralph 	(*putc)(mdev, MOUSE_SELF_TEST);
96356814Sralph 	id_byte1 = (*getc)(mdev);
96456814Sralph 	if (id_byte1 < 0) {
96556814Sralph 		printf("MouseInit: Timeout on 1st byte of self-test report\n");
96656814Sralph 		return;
96756814Sralph 	}
96856814Sralph 	id_byte2 = (*getc)(mdev);
96956814Sralph 	if (id_byte2 < 0) {
97056814Sralph 		printf("MouseInit: Timeout on 2nd byte of self-test report\n");
97156814Sralph 		return;
97256814Sralph 	}
97356814Sralph 	id_byte3 = (*getc)(mdev);
97456814Sralph 	if (id_byte3 < 0) {
97556814Sralph 		printf("MouseInit: Timeout on 3rd byte of self-test report\n");
97656814Sralph 		return;
97756814Sralph 	}
97856814Sralph 	id_byte4 = (*getc)(mdev);
97956814Sralph 	if (id_byte4 < 0) {
98056814Sralph 		printf("MouseInit: Timeout on 4th byte of self-test report\n");
98156814Sralph 		return;
98256814Sralph 	}
98356814Sralph 	if ((id_byte2 & 0x0f) != 0x2)
98456814Sralph 		printf("MouseInit: We don't have a mouse!!!\n");
98556814Sralph 	/*
98656814Sralph 	 * For some reason, the mouse doesn't see this command if it comes
98756814Sralph 	 * too soon after a self test.
98856814Sralph 	 */
98956814Sralph 	DELAY(100);
99056814Sralph 	(*putc)(mdev, MOUSE_INCREMENTAL);
99156814Sralph }
99256814Sralph 
99356814Sralph /*
99456814Sralph  * Get a character off of the keyboard.
99556814Sralph  */
99656814Sralph int
99756814Sralph KBDGetc()
99856814Sralph {
99956814Sralph 	register int c;
100056814Sralph 
100156814Sralph 	for (;;) {
100256814Sralph 		c = (*cn_tab.cn_kbdgetc)(cn_tab.cn_dev);
100356814Sralph 		if (c == 0)
100456814Sralph 			return (-1);
100556814Sralph 		if ((c = kbdMapChar(c & 0xff)) >= 0)
100656814Sralph 			break;
100756814Sralph 	}
100856814Sralph 	return (c);
100956814Sralph }
1010*57234Sralph 
1011*57234Sralph /*
1012*57234Sralph  * Configure the keyboard/mouse based on machine type for turbochannel
1013*57234Sralph  * display boards.
1014*57234Sralph  */
1015*57234Sralph tb_kbdmouseconfig(fp)
1016*57234Sralph 	struct pmax_fb *fp;
1017*57234Sralph {
1018*57234Sralph 
1019*57234Sralph 	switch (pmax_boardtype) {
1020*57234Sralph #if NDC > 0
1021*57234Sralph 	case DS_3MAX:
1022*57234Sralph 		fp->KBDPutc = dcPutc;
1023*57234Sralph 		fp->kbddev = makedev(DCDEV, DCKBD_PORT);
1024*57234Sralph 		break;
1025*57234Sralph #endif
1026*57234Sralph #if NSCC > 0
1027*57234Sralph 	case DS_3MIN:
1028*57234Sralph 	case DS_3MAXPLUS:
1029*57234Sralph 		fp->KBDPutc = sccPutc;
1030*57234Sralph 		fp->kbddev = makedev(SCCDEV, SCCKBD_PORT);
1031*57234Sralph 		break;
1032*57234Sralph #endif
1033*57234Sralph #if NDTOP > 0
1034*57234Sralph 	case DS_MAXINE:
1035*57234Sralph 		fp->KBDPutc = dtopKBDPutc;
1036*57234Sralph 		fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
1037*57234Sralph 		break;
1038*57234Sralph #endif
1039*57234Sralph 	default:
1040*57234Sralph 		printf("Can't configure keyboard/mouse\n");
1041*57234Sralph 		return (1);
1042*57234Sralph 	};
1043*57234Sralph 	return (0);
1044*57234Sralph }
1045