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