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