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