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