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.2 (Berkeley) 12/20/92 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(); 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(); 193 mfbDeconfigMouse(); 194 mfbScreenInit(); 195 vmUserUnmap(); 196 bzero((caddr_t)fp->fr_addr, 256 * 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(256 * 1024, 230 (unsigned)(fp->fr_addr + MFB_OFFSET_VRAM)); 231 if (addr == (caddr_t)0) 232 goto mapError; 233 fp->fbu->scrInfo.bitmap = (char *)addr; 234 break; 235 236 mapError: 237 vmUserUnmap(); 238 printf("Cannot map shared data structures\n"); 239 return (EIO); 240 } 241 242 case QIOCPMSTATE: 243 /* 244 * Set mouse state. 245 */ 246 fp->fbu->scrInfo.mouse = *(pmCursor *)data; 247 mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 248 break; 249 250 case QIOCINIT: 251 /* 252 * Initialize the screen. 253 */ 254 mfbScreenInit(); 255 break; 256 257 case QIOCKPCMD: 258 { 259 pmKpCmd *kpCmdPtr; 260 unsigned char *cp; 261 262 kpCmdPtr = (pmKpCmd *)data; 263 if (kpCmdPtr->nbytes == 0) 264 kpCmdPtr->cmd |= 0x80; 265 if (!fp->GraphicsOpen) 266 kpCmdPtr->cmd |= 1; 267 (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 268 cp = &kpCmdPtr->par[0]; 269 for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 270 if (kpCmdPtr->nbytes == 1) 271 *cp |= 0x80; 272 (*fp->KBDPutc)(fp->kbddev, (int)*cp); 273 } 274 } 275 break; 276 277 case QIOCADDR: 278 *(PM_Info **)data = &fp->fbu->scrInfo; 279 break; 280 281 case QIOWCURSOR: 282 mfbLoadCursor((unsigned short *)data); 283 break; 284 285 case QIOWCURSORCOLOR: 286 mfbCursorColor((unsigned int *)data); 287 break; 288 289 case QIOSETCMAP: 290 mfbLoadColorMap((ColorMap *)data); 291 break; 292 293 case QIOKERNLOOP: 294 mfbConfigMouse(); 295 break; 296 297 case QIOKERNUNLOOP: 298 mfbDeconfigMouse(); 299 break; 300 301 case QIOVIDEOON: 302 mfbRestoreCursorColor(); 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_addr + MFB_OFFSET_BT431); 352 /* 353 * Fill in the cursor sprite using the A and B planes, as provided 354 * for the pmax. 355 * XXX This will have to change when the X server knows that this 356 * is not a pmax display. 357 */ 358 pos = 0; 359 bt431_select_reg(regs, BT431_REG_CRAM_BASE); 360 for (k = 0; k < 16; k++) { 361 ap = *cursor; 362 bp = *(cursor + 16); 363 j = 0; 364 while (j < 2) { 365 out = 0; 366 for (i = 0; i < 8; i++) { 367 #ifdef CURSOR_EL 368 out = (out << 1) | ((ap & 0x1) << 8) | 369 (bp & 0x1); 370 #else 371 out = ((out >> 1) & 0x7f7f) | 372 ((ap & 0x1) << 15) | 373 ((bp & 0x1) << 7); 374 #endif 375 ap >>= 1; 376 bp >>= 1; 377 } 378 BT431_WRITE_CMAP_AUTOI(regs, out); 379 pos++; 380 j++; 381 } 382 while (j < 8) { 383 BT431_WRITE_CMAP_AUTOI(regs, 0); 384 pos++; 385 j++; 386 } 387 cursor++; 388 } 389 while (pos < 512) { 390 BT431_WRITE_CMAP_AUTOI(regs, 0); 391 pos++; 392 } 393 } 394 395 /* 396 * Initialization 397 */ 398 int 399 mfbinit(cp) 400 char *cp; 401 { 402 register struct pmax_fb *fp = &mfbfb; 403 404 /* check for no frame buffer */ 405 if (badaddr(cp, 4)) 406 return (0); 407 408 fp->isMono = 1; 409 fp->fr_addr = (char *)cp; 410 /* 411 * Must be in Uncached space or the Xserver sees a stale version of 412 * the event queue and acts totally wacko. I don't understand this, 413 * since the R3000 uses a physical address cache? 414 */ 415 fp->fbu = (struct fbuaccess *) 416 MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu)); 417 fp->posCursor = mfbPosCursor; 418 if (tb_kbdmouseconfig(fp)) 419 return (0); 420 421 /* 422 * Initialize the screen. 423 */ 424 bt431_init(fp->fr_addr + MFB_OFFSET_BT431); 425 426 /* 427 * Initialize screen info. 428 */ 429 fp->fbu->scrInfo.max_row = 67; 430 fp->fbu->scrInfo.max_col = 80; 431 fp->fbu->scrInfo.max_x = 1280; 432 fp->fbu->scrInfo.max_y = 1024; 433 fp->fbu->scrInfo.max_cur_x = 1279; 434 fp->fbu->scrInfo.max_cur_y = 1023; 435 fp->fbu->scrInfo.version = 11; 436 fp->fbu->scrInfo.mthreshold = 4; 437 fp->fbu->scrInfo.mscale = 2; 438 fp->fbu->scrInfo.min_cur_x = 0; 439 fp->fbu->scrInfo.min_cur_y = 0; 440 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 441 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 442 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 443 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 444 fp->fbu->scrInfo.qe.tcNext = 0; 445 446 /* 447 * Initialize the color map, the screen, and the mouse. 448 */ 449 mfbInitColorMap(); 450 mfbScreenInit(); 451 fbScroll(fp); 452 453 fp->initialized = 1; 454 if (cn_tab.cn_fb == (struct pmax_fb *)0) 455 cn_tab.cn_fb = fp; 456 return (1); 457 } 458 459 /* 460 * ---------------------------------------------------------------------------- 461 * 462 * mfbScreenInit -- 463 * 464 * Initialize the screen. 465 * 466 * Results: 467 * None. 468 * 469 * Side effects: 470 * The screen is initialized. 471 * 472 * ---------------------------------------------------------------------------- 473 */ 474 static void 475 mfbScreenInit() 476 { 477 register struct pmax_fb *fp = &mfbfb; 478 479 /* 480 * Home the cursor. 481 * We want an LSI terminal emulation. We want the graphics 482 * terminal to scroll from the bottom. So start at the bottom. 483 */ 484 fp->row = 66; 485 fp->col = 0; 486 487 /* 488 * Load the cursor with the default values 489 * 490 */ 491 mfbLoadCursor(defCursor); 492 } 493 494 /* 495 * ---------------------------------------------------------------------------- 496 * 497 * RestoreCursorColor -- 498 * 499 * Routine to restore the color of the cursor. 500 * 501 * Results: 502 * None. 503 * 504 * Side effects: 505 * None. 506 * 507 * ---------------------------------------------------------------------------- 508 */ 509 static void 510 mfbRestoreCursorColor() 511 { 512 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 513 ColorMap cm; 514 register int i; 515 516 cm.index = 8; 517 cm.Entry.red = cursor_RGB[0] << 8; 518 cm.Entry.green = cursor_RGB[1] << 8; 519 cm.Entry.blue = cursor_RGB[2] << 8; 520 mfbLoadColorMap(&cm); 521 cm.index = 9; 522 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 523 mfbLoadColorMap(&cm); 524 525 regs->addr_ovly = cursor_RGB[3] >> 4; 526 MachEmptyWriteBuffer(); 527 regs->addr_ovly = cursor_RGB[4] >> 4; 528 MachEmptyWriteBuffer(); 529 regs->addr_ovly = cursor_RGB[5] >> 4; 530 MachEmptyWriteBuffer(); 531 } 532 533 /* 534 * ---------------------------------------------------------------------------- 535 * 536 * CursorColor -- 537 * 538 * Set the color of the cursor. 539 * 540 * Results: 541 * None. 542 * 543 * Side effects: 544 * None. 545 * 546 * ---------------------------------------------------------------------------- 547 */ 548 static void 549 mfbCursorColor(color) 550 unsigned int color[]; 551 { 552 register int i, j; 553 554 for (i = 0; i < 6; i++) 555 cursor_RGB[i] = (u_char)(color[i] >> 8); 556 557 mfbRestoreCursorColor(); 558 } 559 560 /* 561 *---------------------------------------------------------------------- 562 * 563 * PosCursor -- 564 * 565 * Postion the cursor. 566 * 567 * Results: 568 * None. 569 * 570 * Side effects: 571 * None. 572 * 573 *---------------------------------------------------------------------- 574 */ 575 void 576 mfbPosCursor(x, y) 577 register int x, y; 578 { 579 bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431); 580 register struct pmax_fb *fp = &mfbfb; 581 582 if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 583 y = fp->fbu->scrInfo.max_cur_y; 584 if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 585 x = fp->fbu->scrInfo.max_cur_x; 586 fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 587 fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 588 589 #define lo(v) ((v)&0xff) 590 #define hi(v) (((v)&0xf00)>>8) 591 592 /* 593 * Cx = x + D + H - P 594 * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 595 * D = pixel skew between outdata and external data 596 * H = pixels between HSYNCH falling and active video 597 * 598 * Cy = y + V - 32 599 * V = scanlines between HSYNCH falling, two or more 600 * clocks after VSYNCH falling, and active video 601 */ 602 603 bt431_write_reg(regs, lo(x + 360)); 604 BT431_WRITE_REG_AUTOI(regs, hi(x + 360)); 605 BT431_WRITE_REG_AUTOI(regs, lo(y + 36)); 606 BT431_WRITE_REG_AUTOI(regs, hi(y + 36)); 607 } 608 609 /* 610 * ---------------------------------------------------------------------------- 611 * 612 * InitColorMap -- 613 * 614 * Initialize the color map. 615 * 616 * Results: 617 * None. 618 * 619 * Side effects: 620 * The colormap is initialized appropriately. 621 * 622 * ---------------------------------------------------------------------------- 623 */ 624 static void 625 mfbInitColorMap() 626 { 627 ColorMap cm; 628 register int i; 629 630 cm.index = 0; 631 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 632 mfbLoadColorMap(&cm); 633 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 634 for (i = 1; i < 16; i++) { 635 cm.index = i; 636 mfbLoadColorMap(&cm); 637 } 638 639 for (i = 0; i < 3; i++) { 640 cursor_RGB[i] = 0x00; 641 cursor_RGB[i + 3] = 0xff; 642 } 643 mfbRestoreCursorColor(); 644 } 645 646 /* 647 * ---------------------------------------------------------------------------- 648 * 649 * LoadColorMap -- 650 * 651 * Load the color map. 652 * 653 * Results: 654 * None. 655 * 656 * Side effects: 657 * The color map is loaded. 658 * 659 * ---------------------------------------------------------------------------- 660 */ 661 static void 662 mfbLoadColorMap(ptr) 663 ColorMap *ptr; 664 { 665 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 666 667 if (ptr->index > 15) 668 return; 669 670 BT455_SELECT_ENTRY(regs, ptr->index); 671 regs->addr_cmap_data = ptr->Entry.red >> 12; 672 MachEmptyWriteBuffer(); 673 regs->addr_cmap_data = ptr->Entry.green >> 12; 674 MachEmptyWriteBuffer(); 675 regs->addr_cmap_data = ptr->Entry.blue >> 12; 676 MachEmptyWriteBuffer(); 677 } 678 679 /* 680 * Video on/off state. 681 */ 682 static struct vstate { 683 u_char color0[6]; /* saved color map entry zero */ 684 u_char off; /* TRUE if display is off */ 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 703 bt455_video_on() 704 { 705 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 706 707 if (!vstate.off) 708 return; 709 710 /* restore old color map entry zero */ 711 BT455_SELECT_ENTRY(regs, 0); 712 regs->addr_cmap_data = vstate.color0[0]; 713 MachEmptyWriteBuffer(); 714 regs->addr_cmap_data = vstate.color0[1]; 715 MachEmptyWriteBuffer(); 716 regs->addr_cmap_data = vstate.color0[2]; 717 MachEmptyWriteBuffer(); 718 regs->addr_cmap_data = vstate.color0[3]; 719 MachEmptyWriteBuffer(); 720 regs->addr_cmap_data = vstate.color0[4]; 721 MachEmptyWriteBuffer(); 722 regs->addr_cmap_data = vstate.color0[5]; 723 MachEmptyWriteBuffer(); 724 725 vstate.off = 0; 726 } 727 728 /* 729 * ---------------------------------------------------------------------------- 730 * 731 * bt455_video_off 732 * 733 * Disable the video display. 734 * 735 * Results: 736 * None. 737 * 738 * Side effects: 739 * The display is disabled. 740 * 741 * ---------------------------------------------------------------------------- 742 */ 743 static void 744 bt455_video_off() 745 { 746 bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 747 ColorMap cm; 748 749 if (vstate.off) 750 return; 751 752 /* save old color map entry zero */ 753 BT455_SELECT_ENTRY(regs, 0); 754 vstate.color0[0] = regs->addr_cmap_data; 755 vstate.color0[1] = regs->addr_cmap_data; 756 vstate.color0[2] = regs->addr_cmap_data; 757 vstate.color0[3] = regs->addr_cmap_data; 758 vstate.color0[4] = regs->addr_cmap_data; 759 vstate.color0[5] = regs->addr_cmap_data; 760 761 /* set color map entry zero to zero */ 762 cm.index = 0; 763 cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 764 mfbLoadColorMap(&cm); 765 cm.index = 1; 766 mfbLoadColorMap(&cm); 767 768 vstate.off = 1; 769 } 770 771 /* 772 * mfb keyboard and mouse input. Just punt to the generic ones in fb.c 773 */ 774 void 775 mfbKbdEvent(ch) 776 int ch; 777 { 778 fbKbdEvent(ch, &mfbfb); 779 } 780 781 void 782 mfbMouseEvent(newRepPtr) 783 MouseReport *newRepPtr; 784 { 785 fbMouseEvent(newRepPtr, &mfbfb); 786 } 787 788 void 789 mfbMouseButtons(newRepPtr) 790 MouseReport *newRepPtr; 791 { 792 fbMouseButtons(newRepPtr, &mfbfb); 793 } 794 795 /* 796 * Configure the mouse and keyboard based on machine type 797 */ 798 static void 799 mfbConfigMouse() 800 { 801 int s; 802 803 s = spltty(); 804 switch (pmax_boardtype) { 805 #if NDC > 0 806 case DS_3MAX: 807 dcDivertXInput = mfbKbdEvent; 808 dcMouseEvent = mfbMouseEvent; 809 dcMouseButtons = mfbMouseButtons; 810 break; 811 #endif 812 #if NSCC > 1 813 case DS_3MIN: 814 sccDivertXInput = mfbKbdEvent; 815 sccMouseEvent = mfbMouseEvent; 816 sccMouseButtons = mfbMouseButtons; 817 break; 818 #endif 819 #if NDTOP > 0 820 case DS_MAXINE: 821 dtopDivertXInput = mfbKbdEvent; 822 dtopMouseEvent = mfbMouseEvent; 823 dtopMouseButtons = mfbMouseButtons; 824 break; 825 #endif 826 default: 827 printf("Can't configure mouse/keyboard\n"); 828 }; 829 splx(s); 830 } 831 832 /* 833 * and deconfigure them 834 */ 835 static void 836 mfbDeconfigMouse() 837 { 838 int s; 839 840 s = spltty(); 841 switch (pmax_boardtype) { 842 #if NDC > 0 843 case DS_3MAX: 844 dcDivertXInput = (void (*)())0; 845 dcMouseEvent = (void (*)())0; 846 dcMouseButtons = (void (*)())0; 847 break; 848 #endif 849 #if NSCC > 1 850 case DS_3MIN: 851 sccDivertXInput = (void (*)())0; 852 sccMouseEvent = (void (*)())0; 853 sccMouseButtons = (void (*)())0; 854 break; 855 #endif 856 #if NDTOP > 0 857 case DS_MAXINE: 858 dtopDivertXInput = (void (*)())0; 859 dtopMouseEvent = (void (*)())0; 860 dtopMouseButtons = (void (*)())0; 861 break; 862 #endif 863 default: 864 printf("Can't deconfigure mouse/keyboard\n"); 865 }; 866 } 867 868 /* 869 * Generic register access 870 */ 871 static void 872 bt431_select_reg(regs, regno) 873 bt431_regmap_t *regs; 874 { 875 regs->addr_lo = SET_VALUE(regno & 0xff); 876 regs->addr_hi = SET_VALUE((regno >> 8) & 0xff); 877 MachEmptyWriteBuffer(); 878 } 879 880 static void 881 bt431_write_reg(regs, regno, val) 882 bt431_regmap_t *regs; 883 { 884 bt431_select_reg(regs, regno); 885 regs->addr_reg = SET_VALUE(val); 886 MachEmptyWriteBuffer(); 887 } 888 889 static u_char 890 bt431_read_reg(regs, regno) 891 bt431_regmap_t *regs; 892 { 893 bt431_select_reg(regs, regno); 894 return (GET_VALUE(regs->addr_reg)); 895 } 896 897 static void 898 bt431_init(regs) 899 bt431_regmap_t *regs; 900 { 901 register int i; 902 903 /* use 4:1 input mux */ 904 bt431_write_reg(regs, BT431_REG_CMD, 905 BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS| 906 BT431_CMD_4_1_MUX|BT431_CMD_THICK_1); 907 908 /* home cursor */ 909 BT431_WRITE_REG_AUTOI(regs, 0x00); 910 BT431_WRITE_REG_AUTOI(regs, 0x00); 911 BT431_WRITE_REG_AUTOI(regs, 0x00); 912 BT431_WRITE_REG_AUTOI(regs, 0x00); 913 914 /* no crosshair window */ 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 BT431_WRITE_REG_AUTOI(regs, 0x00); 921 BT431_WRITE_REG_AUTOI(regs, 0x00); 922 BT431_WRITE_REG_AUTOI(regs, 0x00); 923 } 924 #endif /* NMFB */ 925