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