PageRenderTime 35ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/sys/pmax/dev/fb.c

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