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