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 * @(#)cfb.c 7.7 (Berkeley) 04/05/93 11 */ 12 13 /* 14 * devGraphics.c -- 15 * 16 * This file contains machine-dependent routines for the graphics device. 17 * 18 * Copyright (C) 1989 Digital Equipment Corporation. 19 * Permission to use, copy, modify, and distribute this software and 20 * its documentation for any purpose and without fee is hereby granted, 21 * provided that the above copyright notice appears in all copies. 22 * Digital Equipment Corporation makes no representations about the 23 * suitability of this software for any purpose. It is provided "as is" 24 * without express or implied warranty. 25 * 26 * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 27 * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 28 */ 29 /* 30 * Mach Operating System 31 * Copyright (c) 1991,1990,1989 Carnegie Mellon University 32 * All Rights Reserved. 33 * 34 * Permission to use, copy, modify and distribute this software and its 35 * documentation is hereby granted, provided that both the copyright 36 * notice and this permission notice appear in all copies of the 37 * software, derivative works or modified versions, and any portions 38 * thereof, and that both notices appear in supporting documentation. 39 * 40 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 41 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 42 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 43 * 44 * Carnegie Mellon requests users of this software to return to 45 * 46 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 47 * School of Computer Science 48 * Carnegie Mellon University 49 * Pittsburgh PA 15213-3890 50 * 51 * any improvements or extensions that they make and grant Carnegie the 52 * rights to redistribute these changes. 53 */ 54 55 #include <cfb.h> 56 #if NCFB > 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/maxine.h> 72 #include <pmax/pmax/cons.h> 73 #include <pmax/pmax/pmaxtype.h> 74 75 #include <pmax/dev/device.h> 76 #include <pmax/dev/cfbreg.h> 77 #include <pmax/dev/fbreg.h> 78 79 #include <dc.h> 80 #include <dtop.h> 81 #include <scc.h> 82 83 /* 84 * These need to be mapped into user space. 85 */ 86 struct fbuaccess cfbu; 87 struct pmax_fb cfbfb; 88 89 /* 90 * Forward references. 91 */ 92 static void cfbScreenInit(); 93 static void cfbLoadCursor(); 94 static void cfbRestoreCursorColor(); 95 static void cfbCursorColor(); 96 void cfbPosCursor(); 97 static void cfbInitColorMap(); 98 static void cfbLoadColorMap(); 99 static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off(); 100 static void bt459_select_reg(), bt459_write_reg(); 101 static u_char bt459_read_reg(); 102 static void cfbConfigMouse(), cfbDeconfigMouse(); 103 104 void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons(); 105 #if NDC > 0 106 extern void (*dcDivertXInput)(); 107 extern void (*dcMouseEvent)(); 108 extern void (*dcMouseButtons)(); 109 #endif 110 #if NSCC > 0 111 extern void (*sccDivertXInput)(); 112 extern void (*sccMouseEvent)(); 113 extern void (*sccMouseButtons)(); 114 #endif 115 #if NDTOP > 0 116 extern void (*dtopDivertXInput)(); 117 extern void (*dtopMouseEvent)(); 118 extern void (*dtopMouseButtons)(); 119 #endif 120 extern int pmax_boardtype; 121 extern u_short defCursor[32]; 122 extern struct consdev cn_tab; 123 124 int cfbprobe(); 125 struct driver cfbdriver = { 126 "cfb", cfbprobe, 0, 0, 127 }; 128 129 #define CFB_OFFSET_VRAM 0x0 /* from module's base */ 130 #define CFB_OFFSET_BT459 0x200000 /* Bt459 registers */ 131 #define CFB_OFFSET_IREQ 0x300000 /* Interrupt req. control */ 132 #define CFB_OFFSET_ROM 0x380000 /* Diagnostic ROM */ 133 #define CFB_OFFSET_RESET 0x3c0000 /* Bt459 resets on writes */ 134 #define CFB_FB_SIZE 0x100000 /* frame buffer size */ 135 136 /* 137 * Test to see if device is present. 138 * Return true if found and initialized ok. 139 */ 140 /*ARGSUSED*/ 141 cfbprobe(cp) 142 register struct pmax_ctlr *cp; 143 { 144 register struct pmax_fb *fp = &cfbfb; 145 146 if (!fp->initialized && !cfbinit(cp->pmax_addr)) 147 return (0); 148 printf("cfb0 (color display)\n"); 149 return (1); 150 } 151 152 /*ARGSUSED*/ 153 cfbopen(dev, flag) 154 dev_t dev; 155 int flag; 156 { 157 register struct pmax_fb *fp = &cfbfb; 158 int s; 159 160 if (!fp->initialized) 161 return (ENXIO); 162 if (fp->GraphicsOpen) 163 return (EBUSY); 164 165 fp->GraphicsOpen = 1; 166 cfbInitColorMap(); 167 /* 168 * Set up event queue for later 169 */ 170 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 171 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 172 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 173 fp->fbu->scrInfo.qe.tcNext = 0; 174 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 175 cfbConfigMouse(); 176 return (0); 177 } 178 179 /*ARGSUSED*/ 180 cfbclose(dev, flag) 181 dev_t dev; 182 int flag; 183 { 184 register struct pmax_fb *fp = &cfbfb; 185 int s; 186 187 if (!fp->GraphicsOpen) 188 return (EBADF); 189 190 fp->GraphicsOpen = 0; 191 cfbInitColorMap(); 192 cfbDeconfigMouse(); 193 cfbScreenInit(); 194 bzero((caddr_t)fp->fr_addr, 1024 * 864); 195 cfbPosCursor(fp->col * 8, fp->row * 15); 196 return (0); 197 } 198 199 /*ARGSUSED*/ 200 cfbioctl(dev, cmd, data, flag, p) 201 dev_t dev; 202 caddr_t data; 203 struct proc *p; 204 { 205 register struct pmax_fb *fp = &cfbfb; 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 cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 218 break; 219 220 case QIOCINIT: 221 /* 222 * Initialize the screen. 223 */ 224 cfbScreenInit(); 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 cfbLoadCursor((unsigned short *)data); 253 break; 254 255 case QIOWCURSORCOLOR: 256 cfbCursorColor((unsigned int *)data); 257 break; 258 259 case QIOSETCMAP: 260 cfbLoadColorMap((ColorMap *)data); 261 break; 262 263 case QIOKERNLOOP: 264 cfbConfigMouse(); 265 break; 266 267 case QIOKERNUNLOOP: 268 cfbDeconfigMouse(); 269 break; 270 271 case QIOVIDEOON: 272 cfbRestoreCursorColor(); 273 bt459_video_on(); 274 break; 275 276 case QIOVIDEOOFF: 277 bt459_video_off(); 278 break; 279 280 default: 281 printf("cfb0: Unknown ioctl command %x\n", cmd); 282 return (EINVAL); 283 } 284 return (0); 285 } 286 287 cfbselect(dev, flag, p) 288 dev_t dev; 289 int flag; 290 struct proc *p; 291 { 292 struct pmax_fb *fp = &cfbfb; 293 294 switch (flag) { 295 case FREAD: 296 if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 297 return (1); 298 selrecord(p, &fp->selp); 299 break; 300 } 301 302 return (0); 303 } 304 305 /* 306 * Return the physical page number that corresponds to byte offset 'off'. 307 */ 308 /*ARGSUSED*/ 309 cfbmap(dev, off, prot) 310 dev_t dev; 311 { 312 int len; 313 314 len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu)); 315 if (off < len) 316 return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off); 317 off -= len; 318 if (off >= cfbfb.fr_size) 319 return (-1); 320 return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off); 321 } 322 323 static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 324 325 /* 326 * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM 327 * defines a 64x64 cursor. If the bt459 does not map the cursor RAM 328 * this way, this code is Screwed! 329 */ 330 static void 331 cfbLoadCursor(cursor) 332 u_short *cursor; 333 { 334 register int i, j, k, pos; 335 register u_short ap, bp, out; 336 337 /* 338 * Fill in the cursor sprite using the A and B planes, as provided 339 * for the pmax. 340 * XXX This will have to change when the X server knows that this 341 * is not a pmax display. 342 */ 343 pos = 0; 344 for (k = 0; k < 16; k++) { 345 ap = *cursor; 346 bp = *(cursor + 16); 347 j = 0; 348 while (j < 4) { 349 out = 0; 350 for (i = 0; i < 4; i++) { 351 #ifdef CURSOR_EL 352 out = (out << 2) | ((ap & 0x1) << 1) | 353 (bp & 0x1); 354 #else 355 out = ((out >> 2) & 0x3f) | 356 ((ap & 0x1) << 7) | 357 ((bp & 0x1) << 6); 358 #endif 359 ap >>= 1; 360 bp >>= 1; 361 } 362 bt459_set_cursor_ram(pos, out); 363 pos++; 364 j++; 365 } 366 while (j < 16) { 367 bt459_set_cursor_ram(pos, 0); 368 pos++; 369 j++; 370 } 371 cursor++; 372 } 373 while (pos < 1024) { 374 bt459_set_cursor_ram(pos, 0); 375 pos++; 376 } 377 } 378 379 /* 380 * Set a cursor ram value. 381 */ 382 static void 383 bt459_set_cursor_ram(pos, val) 384 int pos; 385 register u_char val; 386 { 387 register bt459_regmap_t *regs = (bt459_regmap_t *) 388 (cfbfb.fr_addr + CFB_OFFSET_BT459); 389 register int cnt; 390 u_char nval; 391 392 cnt = 0; 393 do { 394 bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val); 395 nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos); 396 } while (val != nval && ++cnt < 10); 397 } 398 399 /* 400 * Generic register access 401 */ 402 static void 403 bt459_select_reg(regs, regno) 404 bt459_regmap_t *regs; 405 { 406 regs->addr_lo = regno; 407 regs->addr_hi = regno >> 8; 408 MachEmptyWriteBuffer(); 409 } 410 411 static void 412 bt459_write_reg(regs, regno, val) 413 bt459_regmap_t *regs; 414 { 415 regs->addr_lo = regno; 416 regs->addr_hi = regno >> 8; 417 MachEmptyWriteBuffer(); 418 regs->addr_reg = val; 419 MachEmptyWriteBuffer(); 420 } 421 422 static u_char 423 bt459_read_reg(regs, regno) 424 bt459_regmap_t *regs; 425 { 426 regs->addr_lo = regno; 427 regs->addr_hi = regno >> 8; 428 MachEmptyWriteBuffer(); 429 return (regs->addr_reg); 430 } 431 432 /* 433 * Initialization 434 */ 435 int 436 cfbinit(cp) 437 char *cp; 438 { 439 register bt459_regmap_t *regs; 440 register struct pmax_fb *fp = &cfbfb; 441 442 /* check for no frame buffer */ 443 if (badaddr(cp, 4)) 444 return (0); 445 446 fp->isMono = 0; 447 fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM); 448 fp->fr_size = CFB_FB_SIZE; 449 /* 450 * Must be in Uncached space since the fbuaccess structure is 451 * mapped into the user's address space uncached. 452 */ 453 fp->fbu = (struct fbuaccess *) 454 MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu)); 455 fp->posCursor = cfbPosCursor; 456 if (tb_kbdmouseconfig(fp)) 457 return (0); 458 459 /* 460 * Initialize the screen. 461 */ 462 regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459); 463 464 if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a) 465 return (0); 466 467 /* Reset the chip */ 468 *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0; 469 DELAY(2000); /* ???? check right time on specs! ???? */ 470 471 /* use 4:1 input mux */ 472 bt459_write_reg(regs, BT459_REG_CMD0, 0x40); 473 474 /* no zooming, no panning */ 475 bt459_write_reg(regs, BT459_REG_CMD1, 0x00); 476 477 /* 478 * signature test, X-windows cursor, no overlays, SYNC* PLL, 479 * normal RAM select, 7.5 IRE pedestal, do sync 480 */ 481 bt459_write_reg(regs, BT459_REG_CMD2, 0xc2); 482 483 /* get all pixel bits */ 484 bt459_write_reg(regs, BT459_REG_PRM, 0xff); 485 486 /* no blinking */ 487 bt459_write_reg(regs, BT459_REG_PBM, 0x00); 488 489 /* no overlay */ 490 bt459_write_reg(regs, BT459_REG_ORM, 0x00); 491 492 /* no overlay blink */ 493 bt459_write_reg(regs, BT459_REG_OBM, 0x00); 494 495 /* no interleave, no underlay */ 496 bt459_write_reg(regs, BT459_REG_ILV, 0x00); 497 498 /* normal operation, no signature analysis */ 499 bt459_write_reg(regs, BT459_REG_TEST, 0x00); 500 501 /* 502 * no blinking, 1bit cross hair, XOR reg&crosshair, 503 * no crosshair on either plane 0 or 1, 504 * regular cursor on both planes. 505 */ 506 bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 507 508 /* home cursor */ 509 bt459_write_reg(regs, BT459_REG_CXLO, 0x00); 510 bt459_write_reg(regs, BT459_REG_CXHI, 0x00); 511 bt459_write_reg(regs, BT459_REG_CYLO, 0x00); 512 bt459_write_reg(regs, BT459_REG_CYHI, 0x00); 513 514 /* no crosshair window */ 515 bt459_write_reg(regs, BT459_REG_WXLO, 0x00); 516 bt459_write_reg(regs, BT459_REG_WXHI, 0x00); 517 bt459_write_reg(regs, BT459_REG_WYLO, 0x00); 518 bt459_write_reg(regs, BT459_REG_WYHI, 0x00); 519 bt459_write_reg(regs, BT459_REG_WWLO, 0x00); 520 bt459_write_reg(regs, BT459_REG_WWHI, 0x00); 521 bt459_write_reg(regs, BT459_REG_WHLO, 0x00); 522 bt459_write_reg(regs, BT459_REG_WHHI, 0x00); 523 524 /* 525 * Initialize screen info. 526 */ 527 fp->fbu->scrInfo.max_row = 56; 528 fp->fbu->scrInfo.max_col = 80; 529 fp->fbu->scrInfo.max_x = 1024; 530 fp->fbu->scrInfo.max_y = 864; 531 fp->fbu->scrInfo.max_cur_x = 1023; 532 fp->fbu->scrInfo.max_cur_y = 863; 533 fp->fbu->scrInfo.version = 11; 534 fp->fbu->scrInfo.mthreshold = 4; 535 fp->fbu->scrInfo.mscale = 2; 536 fp->fbu->scrInfo.min_cur_x = 0; 537 fp->fbu->scrInfo.min_cur_y = 0; 538 fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 539 fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 540 fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 541 fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 542 fp->fbu->scrInfo.qe.tcNext = 0; 543 544 /* 545 * Initialize the color map, the screen, and the mouse. 546 */ 547 cfbInitColorMap(); 548 cfbScreenInit(); 549 fbScroll(fp); 550 551 fp->initialized = 1; 552 if (cn_tab.cn_fb == (struct pmax_fb *)0) 553 cn_tab.cn_fb = fp; 554 return (1); 555 } 556 557 /* 558 * ---------------------------------------------------------------------------- 559 * 560 * cfbScreenInit -- 561 * 562 * Initialize the screen. 563 * 564 * Results: 565 * None. 566 * 567 * Side effects: 568 * The screen is initialized. 569 * 570 * ---------------------------------------------------------------------------- 571 */ 572 static void 573 cfbScreenInit() 574 { 575 register struct pmax_fb *fp = &cfbfb; 576 577 /* 578 * Home the cursor. 579 * We want an LSI terminal emulation. We want the graphics 580 * terminal to scroll from the bottom. So start at the bottom. 581 */ 582 fp->row = 55; 583 fp->col = 0; 584 585 /* 586 * Load the cursor with the default values 587 * 588 */ 589 cfbLoadCursor(defCursor); 590 } 591 592 /* 593 * ---------------------------------------------------------------------------- 594 * 595 * RestoreCursorColor -- 596 * 597 * Routine to restore the color of the cursor. 598 * 599 * Results: 600 * None. 601 * 602 * Side effects: 603 * None. 604 * 605 * ---------------------------------------------------------------------------- 606 */ 607 static void 608 cfbRestoreCursorColor() 609 { 610 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 611 register int i; 612 613 bt459_select_reg(regs, BT459_REG_CCOLOR_2); 614 for (i = 0; i < 6; i++) { 615 regs->addr_reg = cursor_RGB[i]; 616 MachEmptyWriteBuffer(); 617 } 618 } 619 620 /* 621 * ---------------------------------------------------------------------------- 622 * 623 * CursorColor -- 624 * 625 * Set the color of the cursor. 626 * 627 * Results: 628 * None. 629 * 630 * Side effects: 631 * None. 632 * 633 * ---------------------------------------------------------------------------- 634 */ 635 static void 636 cfbCursorColor(color) 637 unsigned int color[]; 638 { 639 register int i, j; 640 641 for (i = 0; i < 6; i++) 642 cursor_RGB[i] = (u_char)(color[i] >> 8); 643 644 cfbRestoreCursorColor(); 645 } 646 647 /* 648 *---------------------------------------------------------------------- 649 * 650 * PosCursor -- 651 * 652 * Postion the cursor. 653 * 654 * Results: 655 * None. 656 * 657 * Side effects: 658 * None. 659 * 660 *---------------------------------------------------------------------- 661 */ 662 void 663 cfbPosCursor(x, y) 664 register int x, y; 665 { 666 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 667 register struct pmax_fb *fp = &cfbfb; 668 669 if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 670 y = fp->fbu->scrInfo.max_cur_y; 671 if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 672 x = fp->fbu->scrInfo.max_cur_x; 673 fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 674 fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 675 676 x += 219; 677 y += 34; 678 679 bt459_select_reg(regs, BT459_REG_CXLO); 680 regs->addr_reg = x; 681 MachEmptyWriteBuffer(); 682 regs->addr_reg = x >> 8; 683 MachEmptyWriteBuffer(); 684 regs->addr_reg = y; 685 MachEmptyWriteBuffer(); 686 regs->addr_reg = y >> 8; 687 MachEmptyWriteBuffer(); 688 } 689 690 /* 691 * ---------------------------------------------------------------------------- 692 * 693 * InitColorMap -- 694 * 695 * Initialize the color map. 696 * 697 * Results: 698 * None. 699 * 700 * Side effects: 701 * The colormap is initialized appropriately. 702 * 703 * ---------------------------------------------------------------------------- 704 */ 705 static void 706 cfbInitColorMap() 707 { 708 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 709 register int i; 710 711 bt459_select_reg(regs, 0); 712 regs->addr_cmap = 0; MachEmptyWriteBuffer(); 713 regs->addr_cmap = 0; MachEmptyWriteBuffer(); 714 regs->addr_cmap = 0; MachEmptyWriteBuffer(); 715 716 for (i = 1; i < 256; i++) { 717 regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 718 regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 719 regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 720 } 721 722 for (i = 0; i < 3; i++) { 723 cursor_RGB[i] = 0x00; 724 cursor_RGB[i + 3] = 0xff; 725 } 726 cfbRestoreCursorColor(); 727 } 728 729 /* 730 * ---------------------------------------------------------------------------- 731 * 732 * LoadColorMap -- 733 * 734 * Load the color map. 735 * 736 * Results: 737 * None. 738 * 739 * Side effects: 740 * The color map is loaded. 741 * 742 * ---------------------------------------------------------------------------- 743 */ 744 static void 745 cfbLoadColorMap(ptr) 746 ColorMap *ptr; 747 { 748 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 749 750 if (ptr->index > 256) 751 return; 752 753 bt459_select_reg(regs, ptr->index); 754 755 regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer(); 756 regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer(); 757 regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer(); 758 } 759 760 /* 761 * Video on/off state. 762 */ 763 static struct vstate { 764 u_char color0[3]; /* saved color map entry zero */ 765 u_char off; /* TRUE if display is off */ 766 } vstate; 767 768 /* 769 * ---------------------------------------------------------------------------- 770 * 771 * bt459_video_on 772 * 773 * Enable the video display. 774 * 775 * Results: 776 * None. 777 * 778 * Side effects: 779 * The display is enabled. 780 * 781 * ---------------------------------------------------------------------------- 782 */ 783 static void 784 bt459_video_on() 785 { 786 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 787 788 if (!vstate.off) 789 return; 790 791 /* restore old color map entry zero */ 792 bt459_select_reg(regs, 0); 793 regs->addr_cmap = vstate.color0[0]; 794 MachEmptyWriteBuffer(); 795 regs->addr_cmap = vstate.color0[1]; 796 MachEmptyWriteBuffer(); 797 regs->addr_cmap = vstate.color0[2]; 798 MachEmptyWriteBuffer(); 799 800 /* enable normal display */ 801 bt459_write_reg(regs, BT459_REG_PRM, 0xff); 802 bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 803 804 vstate.off = 0; 805 } 806 807 /* 808 * ---------------------------------------------------------------------------- 809 * 810 * bt459_video_off 811 * 812 * Disable the video display. 813 * 814 * Results: 815 * None. 816 * 817 * Side effects: 818 * The display is disabled. 819 * 820 * ---------------------------------------------------------------------------- 821 */ 822 static void 823 bt459_video_off() 824 { 825 bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 826 827 if (vstate.off) 828 return; 829 830 /* save old color map entry zero */ 831 bt459_select_reg(regs, 0); 832 vstate.color0[0] = regs->addr_cmap; 833 vstate.color0[1] = regs->addr_cmap; 834 vstate.color0[2] = regs->addr_cmap; 835 836 /* set color map entry zero to zero */ 837 bt459_select_reg(regs, 0); 838 regs->addr_cmap = 0; 839 MachEmptyWriteBuffer(); 840 regs->addr_cmap = 0; 841 MachEmptyWriteBuffer(); 842 regs->addr_cmap = 0; 843 MachEmptyWriteBuffer(); 844 845 /* disable display */ 846 bt459_write_reg(regs, BT459_REG_PRM, 0); 847 bt459_write_reg(regs, BT459_REG_CCR, 0); 848 849 vstate.off = 1; 850 } 851 852 /* 853 * cfb keyboard and mouse input. Just punt to the generic ones in fb.c 854 */ 855 void 856 cfbKbdEvent(ch) 857 int ch; 858 { 859 fbKbdEvent(ch, &cfbfb); 860 } 861 862 void 863 cfbMouseEvent(newRepPtr) 864 MouseReport *newRepPtr; 865 { 866 fbMouseEvent(newRepPtr, &cfbfb); 867 } 868 869 void 870 cfbMouseButtons(newRepPtr) 871 MouseReport *newRepPtr; 872 { 873 fbMouseButtons(newRepPtr, &cfbfb); 874 } 875 876 /* 877 * Configure the mouse and keyboard based on machine type 878 */ 879 static void 880 cfbConfigMouse() 881 { 882 int s; 883 884 s = spltty(); 885 switch (pmax_boardtype) { 886 #if NDC > 0 887 case DS_3MAX: 888 dcDivertXInput = cfbKbdEvent; 889 dcMouseEvent = cfbMouseEvent; 890 dcMouseButtons = cfbMouseButtons; 891 break; 892 #endif 893 #if NSCC > 1 894 case DS_3MIN: 895 sccDivertXInput = cfbKbdEvent; 896 sccMouseEvent = cfbMouseEvent; 897 sccMouseButtons = cfbMouseButtons; 898 break; 899 #endif 900 #if NDTOP > 0 901 case DS_MAXINE: 902 dtopDivertXInput = cfbKbdEvent; 903 dtopMouseEvent = cfbMouseEvent; 904 dtopMouseButtons = cfbMouseButtons; 905 break; 906 #endif 907 default: 908 printf("Can't configure mouse/keyboard\n"); 909 }; 910 splx(s); 911 } 912 913 /* 914 * and deconfigure them 915 */ 916 static void 917 cfbDeconfigMouse() 918 { 919 int s; 920 921 s = spltty(); 922 switch (pmax_boardtype) { 923 #if NDC > 0 924 case DS_3MAX: 925 dcDivertXInput = (void (*)())0; 926 dcMouseEvent = (void (*)())0; 927 dcMouseButtons = (void (*)())0; 928 break; 929 #endif 930 #if NSCC > 1 931 case DS_3MIN: 932 sccDivertXInput = (void (*)())0; 933 sccMouseEvent = (void (*)())0; 934 sccMouseButtons = (void (*)())0; 935 break; 936 #endif 937 #if NDTOP > 0 938 case DS_MAXINE: 939 dtopDivertXInput = (void (*)())0; 940 dtopMouseEvent = (void (*)())0; 941 dtopMouseButtons = (void (*)())0; 942 break; 943 #endif 944 default: 945 printf("Can't deconfigure mouse/keyboard\n"); 946 }; 947 } 948 #endif /* NCFB */ 949