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