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*58974Sralph * @(#)fb.c 7.4 (Berkeley) 04/05/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> 46*58974Sralph #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> 53*58974Sralph #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 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 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 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 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 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 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 */ 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 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 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 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 } 1059*58974Sralph 1060*58974Sralph /* 1061*58974Sralph * Use vm_mmap() to map the frame buffer and shared data into the user's 1062*58974Sralph * address space. 1063*58974Sralph * Return errno if there was an error. 1064*58974Sralph */ 1065*58974Sralph fbmmap(fp, dev, data, p) 1066*58974Sralph struct pmax_fb *fp; 1067*58974Sralph dev_t dev; 1068*58974Sralph caddr_t data; 1069*58974Sralph struct proc *p; 1070*58974Sralph { 1071*58974Sralph int error; 1072*58974Sralph vm_offset_t addr; 1073*58974Sralph vm_size_t len; 1074*58974Sralph struct vnode vn; 1075*58974Sralph struct specinfo si; 1076*58974Sralph struct fbuaccess *fbp; 1077*58974Sralph 1078*58974Sralph len = pmax_round_page(((vm_offset_t)fp->fbu & PGOFSET) + 1079*58974Sralph sizeof(struct fbuaccess)) + pmax_round_page(fp->fr_size); 1080*58974Sralph addr = (vm_offset_t)0x20000000; /* XXX */ 1081*58974Sralph vn.v_type = VCHR; /* XXX */ 1082*58974Sralph vn.v_specinfo = &si; /* XXX */ 1083*58974Sralph vn.v_rdev = dev; /* XXX */ 1084*58974Sralph /* 1085*58974Sralph * Map the all the data the user needs access to into 1086*58974Sralph * user space. 1087*58974Sralph */ 1088*58974Sralph error = vm_mmap(&p->p_vmspace->vm_map, &addr, len, 1089*58974Sralph VM_PROT_ALL, VM_PROT_ALL, MAP_SHARED, (caddr_t)&vn, 1090*58974Sralph (vm_offset_t)0); 1091*58974Sralph if (error) 1092*58974Sralph return (error); 1093*58974Sralph fbp = (struct fbuaccess *)(addr + ((vm_offset_t)fp->fbu & PGOFSET)); 1094*58974Sralph *(PM_Info **)data = &fbp->scrInfo; 1095*58974Sralph fp->fbu->scrInfo.qe.events = fbp->events; 1096*58974Sralph fp->fbu->scrInfo.qe.tcs = fbp->tcs; 1097*58974Sralph fp->fbu->scrInfo.planemask = (char *)0; 1098*58974Sralph /* 1099*58974Sralph * Map the frame buffer into the user's address space. 1100*58974Sralph */ 1101*58974Sralph fp->fbu->scrInfo.bitmap = (char *)pmax_round_page(fbp + 1); 1102*58974Sralph return (0); 1103*58974Sralph } 1104