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