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 * @(#)mfb.c 8.2 (Berkeley) 06/02/95
11 */
12
13 /*
14 * Mach Operating System
15 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
16 * All Rights Reserved.
17 *
18 * Permission to use, copy, modify and distribute this software and its
19 * documentation is hereby granted, provided that both the copyright
20 * notice and this permission notice appear in all copies of the
21 * software, derivative works or modified versions, and any portions
22 * thereof, and that both notices appear in supporting documentation.
23 *
24 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
25 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
26 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
27 *
28 * Carnegie Mellon requests users of this software to return to
29 *
30 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
31 * School of Computer Science
32 * Carnegie Mellon University
33 * Pittsburgh PA 15213-3890
34 *
35 * any improvements or extensions that they make and grant Carnegie the
36 * rights to redistribute these changes.
37 */
38 /*
39 * devGraphics.c --
40 *
41 * This file contains machine-dependent routines for the graphics device.
42 *
43 * Copyright (C) 1989 Digital Equipment Corporation.
44 * Permission to use, copy, modify, and distribute this software and
45 * its documentation for any purpose and without fee is hereby granted,
46 * provided that the above copyright notice appears in all copies.
47 * Digital Equipment Corporation makes no representations about the
48 * suitability of this software for any purpose. It is provided "as is"
49 * without express or implied warranty.
50 *
51 * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
52 * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
53 */
54
55 #include <mfb.h>
56 #if NMFB > 0
57 #include <sys/param.h>
58 #include <sys/time.h>
59 #include <sys/kernel.h>
60 #include <sys/ioctl.h>
61 #include <sys/file.h>
62 #include <sys/errno.h>
63 #include <sys/proc.h>
64 #include <sys/mman.h>
65
66 #include <vm/vm.h>
67
68 #include <machine/machConst.h>
69 #include <machine/pmioctl.h>
70
71 #include <pmax/pmax/cons.h>
72 #include <pmax/pmax/pmaxtype.h>
73
74 #include <pmax/dev/device.h>
75 #include <pmax/dev/mfbreg.h>
76 #include <pmax/dev/fbreg.h>
77
78 #include <dc.h>
79 #include <dtop.h>
80 #include <scc.h>
81
82 /*
83 * These need to be mapped into user space.
84 */
85 struct fbuaccess mfbu;
86 struct pmax_fb mfbfb;
87
88 /*
89 * Forward references.
90 */
91 static void mfbScreenInit();
92 static void mfbLoadCursor();
93 static void mfbRestoreCursorColor();
94 static void mfbCursorColor();
95 void mfbPosCursor();
96 static void mfbInitColorMap();
97 static void mfbLoadColorMap();
98 static void mfbConfigMouse(), mfbDeconfigMouse();
99 static void bt455_video_on(), bt455_video_off(), bt431_select_reg();
100 static void bt431_write_reg(), bt431_init();
101 static u_char bt431_read_reg();
102
103 void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons();
104 #if NDC > 0
105 extern void (*dcDivertXInput)();
106 extern void (*dcMouseEvent)();
107 extern void (*dcMouseButtons)();
108 #endif
109 #if NSCC > 0
110 extern void (*sccDivertXInput)();
111 extern void (*sccMouseEvent)();
112 extern void (*sccMouseButtons)();
113 #endif
114 #if NDTOP > 0
115 extern void (*dtopDivertXInput)();
116 extern void (*dtopMouseEvent)();
117 extern void (*dtopMouseButtons)();
118 #endif
119 extern int pmax_boardtype;
120 extern u_short defCursor[32];
121 extern struct consdev cn_tab;
122
123 int mfbprobe();
124 struct driver mfbdriver = {
125 "mfb", mfbprobe, 0, 0,
126 };
127
128 #define MFB_OFFSET_VRAM 0x200000 /* from module's base */
129 #define MFB_OFFSET_BT431 0x180000 /* Bt431 registers */
130 #define MFB_OFFSET_BT455 0x100000 /* Bt455 registers */
131 #define MFB_OFFSET_IREQ 0x080000 /* Interrupt req. control */
132 #define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */
133 #define MFB_FB_SIZE 0x200000 /* frame buffer size */
134
135 /*
136 * Test to see if device is present.
137 * Return true if found and initialized ok.
138 */
139 /*ARGSUSED*/
mfbprobe(cp)140 mfbprobe(cp)
141 register struct pmax_ctlr *cp;
142 {
143 register struct pmax_fb *fp = &mfbfb;
144
145 if (!fp->initialized && !mfbinit(cp->pmax_addr))
146 return (0);
147 printf("mfb0 (mono display)\n");
148 return (1);
149 }
150
151 /*ARGSUSED*/
mfbopen(dev,flag)152 mfbopen(dev, flag)
153 dev_t dev;
154 int flag;
155 {
156 register struct pmax_fb *fp = &mfbfb;
157 int s;
158
159 if (!fp->initialized)
160 return (ENXIO);
161 if (fp->GraphicsOpen)
162 return (EBUSY);
163
164 fp->GraphicsOpen = 1;
165 mfbInitColorMap(1);
166 /*
167 * Set up event queue for later
168 */
169 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
170 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
171 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
172 fp->fbu->scrInfo.qe.tcNext = 0;
173 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
174 mfbConfigMouse();
175 return (0);
176 }
177
178 /*ARGSUSED*/
mfbclose(dev,flag)179 mfbclose(dev, flag)
180 dev_t dev;
181 int flag;
182 {
183 register struct pmax_fb *fp = &mfbfb;
184 int s;
185
186 if (!fp->GraphicsOpen)
187 return (EBADF);
188
189 fp->GraphicsOpen = 0;
190 mfbInitColorMap(0);
191 mfbDeconfigMouse();
192 mfbScreenInit();
193 bzero((caddr_t)fp->fr_addr, 2048 * 1024);
194 mfbPosCursor(fp->col * 8, fp->row * 15);
195 return (0);
196 }
197
198 /*ARGSUSED*/
mfbioctl(dev,cmd,data,flag,p)199 mfbioctl(dev, cmd, data, flag, p)
200 dev_t dev;
201 u_long cmd;
202 caddr_t data;
203 struct proc *p;
204 {
205 register struct pmax_fb *fp = &mfbfb;
206 int s;
207
208 switch (cmd) {
209 case QIOCGINFO:
210 return (fbmmap(fp, dev, data, p));
211
212 case QIOCPMSTATE:
213 /*
214 * Set mouse state.
215 */
216 fp->fbu->scrInfo.mouse = *(pmCursor *)data;
217 mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
218 break;
219
220 case QIOCINIT:
221 /*
222 * Initialize the screen.
223 */
224 mfbScreenInit();
225 break;
226
227 case QIOCKPCMD:
228 {
229 pmKpCmd *kpCmdPtr;
230 unsigned char *cp;
231
232 kpCmdPtr = (pmKpCmd *)data;
233 if (kpCmdPtr->nbytes == 0)
234 kpCmdPtr->cmd |= 0x80;
235 if (!fp->GraphicsOpen)
236 kpCmdPtr->cmd |= 1;
237 (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
238 cp = &kpCmdPtr->par[0];
239 for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
240 if (kpCmdPtr->nbytes == 1)
241 *cp |= 0x80;
242 (*fp->KBDPutc)(fp->kbddev, (int)*cp);
243 }
244 break;
245 }
246
247 case QIOCADDR:
248 *(PM_Info **)data = &fp->fbu->scrInfo;
249 break;
250
251 case QIOWCURSOR:
252 mfbLoadCursor((unsigned short *)data);
253 break;
254
255 case QIOWCURSORCOLOR:
256 mfbCursorColor((unsigned int *)data);
257 break;
258
259 case QIOSETCMAP:
260 #ifdef notdef
261 mfbLoadColorMap((ColorMap *)data);
262 #endif
263 break;
264
265 case QIOKERNLOOP:
266 mfbConfigMouse();
267 break;
268
269 case QIOKERNUNLOOP:
270 mfbDeconfigMouse();
271 break;
272
273 case QIOVIDEOON:
274 bt455_video_on();
275 break;
276
277 case QIOVIDEOOFF:
278 bt455_video_off();
279 break;
280
281 default:
282 printf("mfb0: Unknown ioctl command %x\n", cmd);
283 return (EINVAL);
284 }
285 return (0);
286 }
287
288 /*
289 * Return the physical page number that corresponds to byte offset 'off'.
290 */
291 /*ARGSUSED*/
mfbmap(dev,off,prot)292 mfbmap(dev, off, prot)
293 dev_t dev;
294 {
295 int len;
296
297 len = pmax_round_page(((vm_offset_t)&mfbu & PGOFSET) + sizeof(mfbu));
298 if (off < len)
299 return pmax_btop(MACH_CACHED_TO_PHYS(&mfbu) + off);
300 off -= len;
301 if (off >= mfbfb.fr_size)
302 return (-1);
303 return pmax_btop(MACH_UNCACHED_TO_PHYS(mfbfb.fr_addr) + off);
304 }
305
mfbselect(dev,flag,p)306 mfbselect(dev, flag, p)
307 dev_t dev;
308 int flag;
309 struct proc *p;
310 {
311 struct pmax_fb *fp = &mfbfb;
312
313 switch (flag) {
314 case FREAD:
315 if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
316 return (1);
317 selrecord(p, &fp->selp);
318 break;
319 }
320
321 return (0);
322 }
323
324 static u_char cursor_RGB[6]; /* cursor color 2 & 3 */
325
326 /*
327 * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit
328 * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding
329 * registers for these two chips live in adjacent bytes of the shorts that
330 * are defined in bt431_regmap_t.
331 */
332 static void
mfbLoadCursor(cursor)333 mfbLoadCursor(cursor)
334 u_short *cursor;
335 {
336 register int i, j, k, pos;
337 register u_short ap, bp, out;
338 register bt431_regmap_t *regs;
339
340 regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
341 MFB_OFFSET_BT431);
342 /*
343 * Fill in the cursor sprite using the A and B planes, as provided
344 * for the pmax.
345 * XXX This will have to change when the X server knows that this
346 * is not a pmax display. (ie. Not the Xcfbpmax server.)
347 */
348 pos = 0;
349 bt431_select_reg(regs, BT431_REG_CRAM_BASE);
350 for (k = 0; k < 16; k++) {
351 ap = *cursor;
352 bp = *(cursor + 16);
353 j = 0;
354 while (j < 2) {
355 out = 0;
356 for (i = 0; i < 8; i++) {
357 out = (out << 1) | ((bp & 0x1) << 8) |
358 (ap & 0x1);
359 ap >>= 1;
360 bp >>= 1;
361 }
362 BT431_WRITE_CMAP_AUTOI(regs, out);
363 pos++;
364 j++;
365 }
366 while (j < 8) {
367 BT431_WRITE_CMAP_AUTOI(regs, 0);
368 pos++;
369 j++;
370 }
371 cursor++;
372 }
373 while (pos < 512) {
374 BT431_WRITE_CMAP_AUTOI(regs, 0);
375 pos++;
376 }
377 }
378
379 /*
380 * Initialization
381 */
382 int
mfbinit(cp)383 mfbinit(cp)
384 char *cp;
385 {
386 register struct pmax_fb *fp = &mfbfb;
387
388 /* check for no frame buffer */
389 if (badaddr(cp, 4))
390 return (0);
391
392 fp->isMono = 0;
393 fp->fr_addr = cp + MFB_OFFSET_VRAM;
394 fp->fr_chipaddr = cp;
395 fp->fr_size = MFB_FB_SIZE;
396 /*
397 * Must be in Uncached space since the fbuaccess structure is
398 * mapped into the user's address space uncached.
399 */
400 fp->fbu = (struct fbuaccess *)
401 MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu));
402 fp->posCursor = mfbPosCursor;
403 if (tb_kbdmouseconfig(fp))
404 return (0);
405
406 /*
407 * Initialize the screen.
408 */
409 bt431_init(fp->fr_chipaddr + MFB_OFFSET_BT431);
410
411 /*
412 * Initialize screen info.
413 */
414 fp->fbu->scrInfo.max_row = 67;
415 fp->fbu->scrInfo.max_col = 80;
416 fp->fbu->scrInfo.max_x = 1280;
417 fp->fbu->scrInfo.max_y = 1024;
418 fp->fbu->scrInfo.max_cur_x = 1279;
419 fp->fbu->scrInfo.max_cur_y = 1023;
420 fp->fbu->scrInfo.version = 11;
421 fp->fbu->scrInfo.mthreshold = 4;
422 fp->fbu->scrInfo.mscale = 2;
423 fp->fbu->scrInfo.min_cur_x = 0;
424 fp->fbu->scrInfo.min_cur_y = 0;
425 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
426 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
427 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
428 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
429 fp->fbu->scrInfo.qe.tcNext = 0;
430
431 /*
432 * Initialize the color map, the screen, and the mouse.
433 */
434 mfbInitColorMap(0);
435 mfbScreenInit();
436 fbScroll(fp);
437
438 fp->initialized = 1;
439 if (cn_tab.cn_fb == (struct pmax_fb *)0)
440 cn_tab.cn_fb = fp;
441 return (1);
442 }
443
444 /*
445 * ----------------------------------------------------------------------------
446 *
447 * mfbScreenInit --
448 *
449 * Initialize the screen.
450 *
451 * Results:
452 * None.
453 *
454 * Side effects:
455 * The screen is initialized.
456 *
457 * ----------------------------------------------------------------------------
458 */
459 static void
mfbScreenInit()460 mfbScreenInit()
461 {
462 register struct pmax_fb *fp = &mfbfb;
463
464 /*
465 * Home the cursor.
466 * We want an LSI terminal emulation. We want the graphics
467 * terminal to scroll from the bottom. So start at the bottom.
468 */
469 fp->row = 66;
470 fp->col = 0;
471
472 /*
473 * Load the cursor with the default values
474 *
475 */
476 mfbLoadCursor(defCursor);
477 }
478
479 /*
480 * ----------------------------------------------------------------------------
481 *
482 * RestoreCursorColor --
483 *
484 * Routine to restore the color of the cursor.
485 *
486 * Results:
487 * None.
488 *
489 * Side effects:
490 * None.
491 *
492 * ----------------------------------------------------------------------------
493 */
494 static void
mfbRestoreCursorColor()495 mfbRestoreCursorColor()
496 {
497 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
498 MFB_OFFSET_BT455);
499 ColorMap cm;
500 u_char fg;
501
502 if (cursor_RGB[0] || cursor_RGB[1] || cursor_RGB[2])
503 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
504 else
505 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
506 cm.index = 8;
507 mfbLoadColorMap(&cm);
508 cm.index = 9;
509 mfbLoadColorMap(&cm);
510
511 if (cursor_RGB[3] || cursor_RGB[4] || cursor_RGB[5])
512 fg = 0xf;
513 else
514 fg = 0;
515 regs->addr_ovly = fg;
516 MachEmptyWriteBuffer();
517 regs->addr_ovly = fg;
518 MachEmptyWriteBuffer();
519 regs->addr_ovly = fg;
520 MachEmptyWriteBuffer();
521 }
522
523 /*
524 * ----------------------------------------------------------------------------
525 *
526 * CursorColor --
527 *
528 * Set the color of the cursor.
529 *
530 * Results:
531 * None.
532 *
533 * Side effects:
534 * None.
535 *
536 * ----------------------------------------------------------------------------
537 */
538 static void
mfbCursorColor(color)539 mfbCursorColor(color)
540 unsigned int color[];
541 {
542 register int i, j;
543
544 for (i = 0; i < 6; i++)
545 cursor_RGB[i] = (u_char)(color[i] >> 8);
546
547 mfbRestoreCursorColor();
548 }
549
550 /*
551 *----------------------------------------------------------------------
552 *
553 * PosCursor --
554 *
555 * Postion the cursor.
556 *
557 * Results:
558 * None.
559 *
560 * Side effects:
561 * None.
562 *
563 *----------------------------------------------------------------------
564 */
565 void
mfbPosCursor(x,y)566 mfbPosCursor(x, y)
567 register int x, y;
568 {
569 bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
570 MFB_OFFSET_BT431);
571 register struct pmax_fb *fp = &mfbfb;
572
573 if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
574 y = fp->fbu->scrInfo.max_cur_y;
575 if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
576 x = fp->fbu->scrInfo.max_cur_x;
577 fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
578 fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
579
580 #define lo(v) ((v)&0xff)
581 #define hi(v) (((v)&0xf00)>>8)
582
583 /*
584 * Cx = x + D + H - P
585 * P = 37 if 1:1, 52 if 4:1, 57 if 5:1
586 * D = pixel skew between outdata and external data
587 * H = pixels between HSYNCH falling and active video
588 *
589 * Cy = y + V - 32
590 * V = scanlines between HSYNCH falling, two or more
591 * clocks after VSYNCH falling, and active video
592 */
593
594 bt431_write_reg(regs, BT431_REG_CXLO, lo(x + 360));
595 BT431_WRITE_REG_AUTOI(regs, hi(x + 360));
596 BT431_WRITE_REG_AUTOI(regs, lo(y + 36));
597 BT431_WRITE_REG_AUTOI(regs, hi(y + 36));
598 }
599
600 /*
601 * ----------------------------------------------------------------------------
602 *
603 * InitColorMap --
604 *
605 * Initialize the color map.
606 *
607 * Results:
608 * None.
609 *
610 * Side effects:
611 * The colormap is initialized appropriately.
612 *
613 * ----------------------------------------------------------------------------
614 */
615 static void
mfbInitColorMap(blackpix)616 mfbInitColorMap(blackpix)
617 int blackpix;
618 {
619 ColorMap cm;
620 register int i;
621
622 cm.index = 0;
623 if (blackpix)
624 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
625 else
626 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
627 mfbLoadColorMap(&cm);
628 if (blackpix)
629 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
630 else
631 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
632 for (i = 1; i < 16; i++) {
633 cm.index = i;
634 mfbLoadColorMap(&cm);
635 }
636
637 for (i = 0; i < 3; i++) {
638 cursor_RGB[i] = 0;
639 cursor_RGB[i + 3] = 0xff;
640 }
641 mfbRestoreCursorColor();
642 }
643
644 /*
645 * ----------------------------------------------------------------------------
646 *
647 * LoadColorMap --
648 *
649 * Load the color map.
650 *
651 * Results:
652 * None.
653 *
654 * Side effects:
655 * The color map is loaded.
656 *
657 * ----------------------------------------------------------------------------
658 */
659 static void
mfbLoadColorMap(ptr)660 mfbLoadColorMap(ptr)
661 ColorMap *ptr;
662 {
663 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
664 MFB_OFFSET_BT455);
665
666 if (ptr->index > 15)
667 return;
668
669 BT455_SELECT_ENTRY(regs, ptr->index);
670 regs->addr_cmap_data = ptr->Entry.red >> 12;
671 MachEmptyWriteBuffer();
672 regs->addr_cmap_data = ptr->Entry.green >> 12;
673 MachEmptyWriteBuffer();
674 regs->addr_cmap_data = ptr->Entry.blue >> 12;
675 MachEmptyWriteBuffer();
676 }
677
678 /*
679 * Video on/off state.
680 */
681 static struct vstate {
682 u_char color0[6]; /* saved color map entry zero */
683 u_char off; /* TRUE if display is off */
684 u_char cursor[6]; /* saved cursor color */
685 } vstate;
686
687 /*
688 * ----------------------------------------------------------------------------
689 *
690 * bt455_video_on
691 *
692 * Enable the video display.
693 *
694 * Results:
695 * None.
696 *
697 * Side effects:
698 * The display is enabled.
699 *
700 * ----------------------------------------------------------------------------
701 */
702 static void
bt455_video_on()703 bt455_video_on()
704 {
705 register int i;
706 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
707 MFB_OFFSET_BT455);
708
709 if (!vstate.off)
710 return;
711
712 /* restore old color map entry zero */
713 BT455_SELECT_ENTRY(regs, 0);
714 for (i = 0; i < 6; i++) {
715 regs->addr_cmap_data = vstate.color0[i];
716 MachEmptyWriteBuffer();
717 cursor_RGB[i] = vstate.cursor[i];
718 }
719 mfbRestoreCursorColor();
720 vstate.off = 0;
721 }
722
723 /*
724 * ----------------------------------------------------------------------------
725 *
726 * bt455_video_off
727 *
728 * Disable the video display.
729 *
730 * Results:
731 * None.
732 *
733 * Side effects:
734 * The display is disabled.
735 *
736 * ----------------------------------------------------------------------------
737 */
738 static void
bt455_video_off()739 bt455_video_off()
740 {
741 register int i;
742 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
743 MFB_OFFSET_BT455);
744 ColorMap cm;
745
746 if (vstate.off)
747 return;
748
749 /* save old color map entry zero */
750 BT455_SELECT_ENTRY(regs, 0);
751 for (i = 0; i < 6; i++) {
752 vstate.color0[i] = regs->addr_cmap_data;
753 vstate.cursor[i] = cursor_RGB[i];
754 cursor_RGB[i] = 0;
755 }
756
757 /* set color map entry zero to zero */
758 cm.index = 0;
759 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
760 mfbLoadColorMap(&cm);
761 cm.index = 1;
762 mfbLoadColorMap(&cm);
763
764 mfbRestoreCursorColor();
765 vstate.off = 1;
766 }
767
768 /*
769 * mfb keyboard and mouse input. Just punt to the generic ones in fb.c
770 */
771 void
mfbKbdEvent(ch)772 mfbKbdEvent(ch)
773 int ch;
774 {
775 fbKbdEvent(ch, &mfbfb);
776 }
777
778 void
mfbMouseEvent(newRepPtr)779 mfbMouseEvent(newRepPtr)
780 MouseReport *newRepPtr;
781 {
782 fbMouseEvent(newRepPtr, &mfbfb);
783 }
784
785 void
mfbMouseButtons(newRepPtr)786 mfbMouseButtons(newRepPtr)
787 MouseReport *newRepPtr;
788 {
789 fbMouseButtons(newRepPtr, &mfbfb);
790 }
791
792 /*
793 * Configure the mouse and keyboard based on machine type
794 */
795 static void
mfbConfigMouse()796 mfbConfigMouse()
797 {
798 int s;
799
800 s = spltty();
801 switch (pmax_boardtype) {
802 #if NDC > 0
803 case DS_3MAX:
804 dcDivertXInput = mfbKbdEvent;
805 dcMouseEvent = mfbMouseEvent;
806 dcMouseButtons = mfbMouseButtons;
807 break;
808 #endif
809 #if NSCC > 1
810 case DS_3MIN:
811 sccDivertXInput = mfbKbdEvent;
812 sccMouseEvent = mfbMouseEvent;
813 sccMouseButtons = mfbMouseButtons;
814 break;
815 #endif
816 #if NDTOP > 0
817 case DS_MAXINE:
818 dtopDivertXInput = mfbKbdEvent;
819 dtopMouseEvent = mfbMouseEvent;
820 dtopMouseButtons = mfbMouseButtons;
821 break;
822 #endif
823 default:
824 printf("Can't configure mouse/keyboard\n");
825 };
826 splx(s);
827 }
828
829 /*
830 * and deconfigure them
831 */
832 static void
mfbDeconfigMouse()833 mfbDeconfigMouse()
834 {
835 int s;
836
837 s = spltty();
838 switch (pmax_boardtype) {
839 #if NDC > 0
840 case DS_3MAX:
841 dcDivertXInput = (void (*)())0;
842 dcMouseEvent = (void (*)())0;
843 dcMouseButtons = (void (*)())0;
844 break;
845 #endif
846 #if NSCC > 1
847 case DS_3MIN:
848 sccDivertXInput = (void (*)())0;
849 sccMouseEvent = (void (*)())0;
850 sccMouseButtons = (void (*)())0;
851 break;
852 #endif
853 #if NDTOP > 0
854 case DS_MAXINE:
855 dtopDivertXInput = (void (*)())0;
856 dtopMouseEvent = (void (*)())0;
857 dtopMouseButtons = (void (*)())0;
858 break;
859 #endif
860 default:
861 printf("Can't deconfigure mouse/keyboard\n");
862 };
863 }
864
865 /*
866 * Generic register access
867 */
868 static void
bt431_select_reg(regs,regno)869 bt431_select_reg(regs, regno)
870 bt431_regmap_t *regs;
871 {
872 regs->addr_lo = SET_VALUE(regno & 0xff);
873 regs->addr_hi = SET_VALUE((regno >> 8) & 0xff);
874 MachEmptyWriteBuffer();
875 }
876
877 static void
bt431_write_reg(regs,regno,val)878 bt431_write_reg(regs, regno, val)
879 bt431_regmap_t *regs;
880 {
881 bt431_select_reg(regs, regno);
882 regs->addr_reg = SET_VALUE(val);
883 MachEmptyWriteBuffer();
884 }
885
886 static u_char
bt431_read_reg(regs,regno)887 bt431_read_reg(regs, regno)
888 bt431_regmap_t *regs;
889 {
890 bt431_select_reg(regs, regno);
891 return (GET_VALUE(regs->addr_reg));
892 }
893
894 static void
bt431_init(regs)895 bt431_init(regs)
896 bt431_regmap_t *regs;
897 {
898 register int i;
899
900 /* use 4:1 input mux */
901 bt431_write_reg(regs, BT431_REG_CMD,
902 BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS|
903 BT431_CMD_4_1_MUX|BT431_CMD_THICK_1);
904
905 /* home cursor */
906 BT431_WRITE_REG_AUTOI(regs, 0x00);
907 BT431_WRITE_REG_AUTOI(regs, 0x00);
908 BT431_WRITE_REG_AUTOI(regs, 0x00);
909 BT431_WRITE_REG_AUTOI(regs, 0x00);
910
911 /* no crosshair window */
912 BT431_WRITE_REG_AUTOI(regs, 0x00);
913 BT431_WRITE_REG_AUTOI(regs, 0x00);
914 BT431_WRITE_REG_AUTOI(regs, 0x00);
915 BT431_WRITE_REG_AUTOI(regs, 0x00);
916 BT431_WRITE_REG_AUTOI(regs, 0x00);
917 BT431_WRITE_REG_AUTOI(regs, 0x00);
918 BT431_WRITE_REG_AUTOI(regs, 0x00);
919 BT431_WRITE_REG_AUTOI(regs, 0x00);
920 }
921 #endif /* NMFB */
922