1*56815Sralph /*- 2*56815Sralph * Copyright (c) 1992 The Regents of the University of California. 3*56815Sralph * All rights reserved. 4*56815Sralph * 5*56815Sralph * This code is derived from software contributed to Berkeley by 6*56815Sralph * Ralph Campbell and Rick Macklem. 7*56815Sralph * 8*56815Sralph * %sccs.include.redist.c% 9*56815Sralph * 10*56815Sralph * @(#)mfb.c 7.1 (Berkeley) 11/15/92 11*56815Sralph */ 12*56815Sralph 13*56815Sralph /* 14*56815Sralph * Mach Operating System 15*56815Sralph * Copyright (c) 1991,1990,1989 Carnegie Mellon University 16*56815Sralph * All Rights Reserved. 17*56815Sralph * 18*56815Sralph * Permission to use, copy, modify and distribute this software and its 19*56815Sralph * documentation is hereby granted, provided that both the copyright 20*56815Sralph * notice and this permission notice appear in all copies of the 21*56815Sralph * software, derivative works or modified versions, and any portions 22*56815Sralph * thereof, and that both notices appear in supporting documentation. 23*56815Sralph * 24*56815Sralph * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 25*56815Sralph * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 26*56815Sralph * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 27*56815Sralph * 28*56815Sralph * Carnegie Mellon requests users of this software to return to 29*56815Sralph * 30*56815Sralph * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 31*56815Sralph * School of Computer Science 32*56815Sralph * Carnegie Mellon University 33*56815Sralph * Pittsburgh PA 15213-3890 34*56815Sralph * 35*56815Sralph * any improvements or extensions that they make and grant Carnegie the 36*56815Sralph * rights to redistribute these changes. 37*56815Sralph */ 38*56815Sralph /* 39*56815Sralph * devGraphics.c -- 40*56815Sralph * 41*56815Sralph * This file contains machine-dependent routines for the graphics device. 42*56815Sralph * 43*56815Sralph * Copyright (C) 1989 Digital Equipment Corporation. 44*56815Sralph * Permission to use, copy, modify, and distribute this software and 45*56815Sralph * its documentation for any purpose and without fee is hereby granted, 46*56815Sralph * provided that the above copyright notice appears in all copies. 47*56815Sralph * Digital Equipment Corporation makes no representations about the 48*56815Sralph * suitability of this software for any purpose. It is provided "as is" 49*56815Sralph * without express or implied warranty. 50*56815Sralph * 51*56815Sralph * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 52*56815Sralph * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 53*56815Sralph */ 54*56815Sralph 55*56815Sralph #include <mfb.h> 56*56815Sralph #if NMFB > 0 57*56815Sralph #include <sys/param.h> 58*56815Sralph #include <sys/time.h> 59*56815Sralph #include <sys/kernel.h> 60*56815Sralph #include <sys/ioctl.h> 61*56815Sralph #include <sys/file.h> 62*56815Sralph #include <sys/errno.h> 63*56815Sralph #include <sys/proc.h> 64*56815Sralph #include <sys/mman.h> 65*56815Sralph 66*56815Sralph #include <vm/vm.h> 67*56815Sralph 68*56815Sralph #include <machine/machConst.h> 69*56815Sralph #include <machine/pmioctl.h> 70*56815Sralph 71*56815Sralph #include <pmax/pmax/cons.h> 72*56815Sralph #include <pmax/pmax/pmaxtype.h> 73*56815Sralph 74*56815Sralph #include <pmax/dev/device.h> 75*56815Sralph #include <pmax/dev/mfbreg.h> 76*56815Sralph #include <pmax/dev/fbreg.h> 77*56815Sralph 78*56815Sralph #include <dc.h> 79*56815Sralph #include <dtop.h> 80*56815Sralph #include <scc.h> 81*56815Sralph 82*56815Sralph /* 83*56815Sralph * These need to be mapped into user space. 84*56815Sralph */ 85*56815Sralph struct fbuaccess mfbu; 86*56815Sralph struct pmax_fb mfbfb; 87*56815Sralph 88*56815Sralph /* 89*56815Sralph * Forward references. 90*56815Sralph */ 91*56815Sralph extern void fbScroll(); 92*56815Sralph 93*56815Sralph static void mfbScreenInit(); 94*56815Sralph static void mfbLoadCursor(); 95*56815Sralph static void mfbRestoreCursorColor(); 96*56815Sralph static void mfbCursorColor(); 97*56815Sralph void mfbPosCursor(); 98*56815Sralph static void mfbInitColorMap(); 99*56815Sralph static void mfbLoadColorMap(); 100*56815Sralph static void mfbConfigMouse(), mfbDeconfigMouse(); 101*56815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg(); 102*56815Sralph static void bt431_write_reg(), bt431_init(); 103*56815Sralph static u_char bt431_read_reg(); 104*56815Sralph 105*56815Sralph extern void fbKbdEvent(), fbMouseEvent(), fbMouseButtons(); 106*56815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons(); 107*56815Sralph #if NDC > 0 108*56815Sralph #include <machine/dc7085cons.h> 109*56815Sralph extern void dcPutc(); 110*56815Sralph extern void (*dcDivertXInput)(); 111*56815Sralph extern void (*dcMouseEvent)(); 112*56815Sralph extern void (*dcMouseButtons)(); 113*56815Sralph #endif 114*56815Sralph #if NSCC > 0 115*56815Sralph #include <pmax/dev/sccreg.h> 116*56815Sralph extern void sccPutc(); 117*56815Sralph extern void (*sccDivertXInput)(); 118*56815Sralph extern void (*sccMouseEvent)(); 119*56815Sralph extern void (*sccMouseButtons)(); 120*56815Sralph #endif 121*56815Sralph #if NDTOP > 0 122*56815Sralph #include <pmax/dev/dtopreg.h> 123*56815Sralph extern void dtopKBDPutc(); 124*56815Sralph extern void (*dtopDivertXInput)(); 125*56815Sralph extern void (*dtopMouseEvent)(); 126*56815Sralph extern void (*dtopMouseButtons)(); 127*56815Sralph #endif 128*56815Sralph extern int pmax_boardtype; 129*56815Sralph extern u_short defCursor[32]; 130*56815Sralph extern struct consdev cn_tab; 131*56815Sralph 132*56815Sralph int mfbprobe(); 133*56815Sralph struct driver mfbdriver = { 134*56815Sralph "mfb", mfbprobe, 0, 0, 135*56815Sralph }; 136*56815Sralph 137*56815Sralph #define MFB_OFFSET_VRAM 0x200000 /* from module's base */ 138*56815Sralph #define MFB_OFFSET_BT431 0x180000 /* Bt431 registers */ 139*56815Sralph #define MFB_OFFSET_BT455 0x100000 /* Bt455 registers */ 140*56815Sralph #define MFB_OFFSET_IREQ 0x080000 /* Interrupt req. control */ 141*56815Sralph #define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */ 142*56815Sralph 143*56815Sralph /* 144*56815Sralph * Test to see if device is present. 145*56815Sralph * Return true if found and initialized ok. 146*56815Sralph */ 147*56815Sralph /*ARGSUSED*/ 148*56815Sralph mfbprobe(cp) 149*56815Sralph register struct pmax_ctlr *cp; 150*56815Sralph { 151*56815Sralph register struct pmax_fb *fp = &mfbfb; 152*56815Sralph 153*56815Sralph if (!fp->initialized && !mfbinit(cp->pmax_addr)) 154*56815Sralph return (0); 155*56815Sralph printf("mfb0 (mono display)\n"); 156*56815Sralph return (1); 157*56815Sralph } 158*56815Sralph 159*56815Sralph /*ARGSUSED*/ 160*56815Sralph mfbopen(dev, flag) 161*56815Sralph dev_t dev; 162*56815Sralph int flag; 163*56815Sralph { 164*56815Sralph register struct pmax_fb *fp = &mfbfb; 165*56815Sralph int s; 166*56815Sralph 167*56815Sralph if (!fp->initialized) 168*56815Sralph return (ENXIO); 169*56815Sralph if (fp->GraphicsOpen) 170*56815Sralph return (EBUSY); 171*56815Sralph 172*56815Sralph fp->GraphicsOpen = 1; 173*56815Sralph mfbInitColorMap(); 174*56815Sralph /* 175*56815Sralph * Set up event queue for later 176*56815Sralph */ 177*56815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 178*56815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 179*56815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 180*56815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 181*56815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 182*56815Sralph mfbConfigMouse(); 183*56815Sralph return (0); 184*56815Sralph } 185*56815Sralph 186*56815Sralph /*ARGSUSED*/ 187*56815Sralph mfbclose(dev, flag) 188*56815Sralph dev_t dev; 189*56815Sralph int flag; 190*56815Sralph { 191*56815Sralph register struct pmax_fb *fp = &mfbfb; 192*56815Sralph int s; 193*56815Sralph 194*56815Sralph if (!fp->GraphicsOpen) 195*56815Sralph return (EBADF); 196*56815Sralph 197*56815Sralph fp->GraphicsOpen = 0; 198*56815Sralph mfbInitColorMap(); 199*56815Sralph mfbDeconfigMouse(); 200*56815Sralph mfbScreenInit(); 201*56815Sralph vmUserUnmap(); 202*56815Sralph bzero((caddr_t)fp->fr_addr, 256 * 1024); 203*56815Sralph mfbPosCursor(fp->col * 8, fp->row * 15); 204*56815Sralph return (0); 205*56815Sralph } 206*56815Sralph 207*56815Sralph /*ARGSUSED*/ 208*56815Sralph mfbioctl(dev, cmd, data, flag) 209*56815Sralph dev_t dev; 210*56815Sralph caddr_t data; 211*56815Sralph { 212*56815Sralph register struct pmax_fb *fp = &mfbfb; 213*56815Sralph int s; 214*56815Sralph 215*56815Sralph switch (cmd) { 216*56815Sralph case QIOCGINFO: 217*56815Sralph { 218*56815Sralph caddr_t addr; 219*56815Sralph extern caddr_t vmUserMap(); 220*56815Sralph 221*56815Sralph /* 222*56815Sralph * Map the all the data the user needs access to into 223*56815Sralph * user space. 224*56815Sralph */ 225*56815Sralph addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu); 226*56815Sralph if (addr == (caddr_t)0) 227*56815Sralph goto mapError; 228*56815Sralph *(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo; 229*56815Sralph fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events; 230*56815Sralph fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs; 231*56815Sralph fp->fbu->scrInfo.planemask = (char *)0; 232*56815Sralph /* 233*56815Sralph * Map the frame buffer into the user's address space. 234*56815Sralph */ 235*56815Sralph addr = vmUserMap(256 * 1024, 236*56815Sralph (unsigned)(fp->fr_addr + MFB_OFFSET_VRAM)); 237*56815Sralph if (addr == (caddr_t)0) 238*56815Sralph goto mapError; 239*56815Sralph fp->fbu->scrInfo.bitmap = (char *)addr; 240*56815Sralph break; 241*56815Sralph 242*56815Sralph mapError: 243*56815Sralph vmUserUnmap(); 244*56815Sralph printf("Cannot map shared data structures\n"); 245*56815Sralph return (EIO); 246*56815Sralph } 247*56815Sralph 248*56815Sralph case QIOCPMSTATE: 249*56815Sralph /* 250*56815Sralph * Set mouse state. 251*56815Sralph */ 252*56815Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 253*56815Sralph mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 254*56815Sralph break; 255*56815Sralph 256*56815Sralph case QIOCINIT: 257*56815Sralph /* 258*56815Sralph * Initialize the screen. 259*56815Sralph */ 260*56815Sralph mfbScreenInit(); 261*56815Sralph break; 262*56815Sralph 263*56815Sralph case QIOCKPCMD: 264*56815Sralph { 265*56815Sralph pmKpCmd *kpCmdPtr; 266*56815Sralph unsigned char *cp; 267*56815Sralph 268*56815Sralph kpCmdPtr = (pmKpCmd *)data; 269*56815Sralph if (kpCmdPtr->nbytes == 0) 270*56815Sralph kpCmdPtr->cmd |= 0x80; 271*56815Sralph if (!fp->GraphicsOpen) 272*56815Sralph kpCmdPtr->cmd |= 1; 273*56815Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 274*56815Sralph cp = &kpCmdPtr->par[0]; 275*56815Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 276*56815Sralph if (kpCmdPtr->nbytes == 1) 277*56815Sralph *cp |= 0x80; 278*56815Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 279*56815Sralph } 280*56815Sralph } 281*56815Sralph break; 282*56815Sralph 283*56815Sralph case QIOCADDR: 284*56815Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 285*56815Sralph break; 286*56815Sralph 287*56815Sralph case QIOWCURSOR: 288*56815Sralph mfbLoadCursor((unsigned short *)data); 289*56815Sralph break; 290*56815Sralph 291*56815Sralph case QIOWCURSORCOLOR: 292*56815Sralph mfbCursorColor((unsigned int *)data); 293*56815Sralph break; 294*56815Sralph 295*56815Sralph case QIOSETCMAP: 296*56815Sralph mfbLoadColorMap((ColorMap *)data); 297*56815Sralph break; 298*56815Sralph 299*56815Sralph case QIOKERNLOOP: 300*56815Sralph mfbConfigMouse(); 301*56815Sralph break; 302*56815Sralph 303*56815Sralph case QIOKERNUNLOOP: 304*56815Sralph mfbDeconfigMouse(); 305*56815Sralph break; 306*56815Sralph 307*56815Sralph case QIOVIDEOON: 308*56815Sralph mfbRestoreCursorColor(); 309*56815Sralph bt455_video_on(); 310*56815Sralph break; 311*56815Sralph 312*56815Sralph case QIOVIDEOOFF: 313*56815Sralph bt455_video_off(); 314*56815Sralph break; 315*56815Sralph 316*56815Sralph default: 317*56815Sralph printf("mfb0: Unknown ioctl command %x\n", cmd); 318*56815Sralph return (EINVAL); 319*56815Sralph } 320*56815Sralph return (0); 321*56815Sralph } 322*56815Sralph 323*56815Sralph mfbselect(dev, flag, p) 324*56815Sralph dev_t dev; 325*56815Sralph int flag; 326*56815Sralph struct proc *p; 327*56815Sralph { 328*56815Sralph struct pmax_fb *fp = &mfbfb; 329*56815Sralph 330*56815Sralph switch (flag) { 331*56815Sralph case FREAD: 332*56815Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 333*56815Sralph return (1); 334*56815Sralph selrecord(p, &fp->selp); 335*56815Sralph break; 336*56815Sralph } 337*56815Sralph 338*56815Sralph return (0); 339*56815Sralph } 340*56815Sralph 341*56815Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 342*56815Sralph 343*56815Sralph /* 344*56815Sralph * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit 345*56815Sralph * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding 346*56815Sralph * registers for these two chips live in adjacent bytes of the shorts that 347*56815Sralph * are defined in bt431_regmap_t. 348*56815Sralph */ 349*56815Sralph static void 350*56815Sralph mfbLoadCursor(cursor) 351*56815Sralph u_short *cursor; 352*56815Sralph { 353*56815Sralph register int i, j, k, pos; 354*56815Sralph register u_short ap, bp, out; 355*56815Sralph register bt431_regmap_t *regs; 356*56815Sralph 357*56815Sralph regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431); 358*56815Sralph /* 359*56815Sralph * Fill in the cursor sprite using the A and B planes, as provided 360*56815Sralph * for the pmax. 361*56815Sralph * XXX This will have to change when the X server knows that this 362*56815Sralph * is not a pmax display. 363*56815Sralph */ 364*56815Sralph pos = 0; 365*56815Sralph bt431_select_reg(regs, BT431_REG_CRAM_BASE); 366*56815Sralph for (k = 0; k < 16; k++) { 367*56815Sralph ap = *cursor; 368*56815Sralph bp = *(cursor + 16); 369*56815Sralph j = 0; 370*56815Sralph while (j < 2) { 371*56815Sralph out = 0; 372*56815Sralph for (i = 0; i < 8; i++) { 373*56815Sralph out = (out << 1) | ((ap & 0x1) << 8) | 374*56815Sralph (bp & 0x1); 375*56815Sralph ap >>= 1; 376*56815Sralph bp >>= 1; 377*56815Sralph } 378*56815Sralph BT431_WRITE_CMAP_AUTOI(regs, out); 379*56815Sralph pos++; 380*56815Sralph j++; 381*56815Sralph } 382*56815Sralph while (j < 8) { 383*56815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 384*56815Sralph pos++; 385*56815Sralph j++; 386*56815Sralph } 387*56815Sralph cursor++; 388*56815Sralph } 389*56815Sralph while (pos < 512) { 390*56815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 391*56815Sralph pos++; 392*56815Sralph } 393*56815Sralph } 394*56815Sralph 395*56815Sralph /* 396*56815Sralph * Initialization 397*56815Sralph */ 398*56815Sralph int 399*56815Sralph mfbinit(cp) 400*56815Sralph char *cp; 401*56815Sralph { 402*56815Sralph register struct pmax_fb *fp = &mfbfb; 403*56815Sralph 404*56815Sralph /* check for no frame buffer */ 405*56815Sralph if (badaddr(cp, 4)) 406*56815Sralph return (0); 407*56815Sralph 408*56815Sralph fp->isMono = 1; 409*56815Sralph fp->fr_addr = (char *)cp; 410*56815Sralph fp->fbu = &mfbu; 411*56815Sralph fp->posCursor = mfbPosCursor; 412*56815Sralph switch (pmax_boardtype) { 413*56815Sralph #if NDC > 0 414*56815Sralph case DS_3MAX: 415*56815Sralph fp->KBDPutc = dcPutc; 416*56815Sralph fp->kbddev = makedev(DCDEV, DCKBD_PORT); 417*56815Sralph break; 418*56815Sralph #endif 419*56815Sralph #if NSCC > 0 420*56815Sralph case DS_3MIN: 421*56815Sralph fp->KBDPutc = sccPutc; 422*56815Sralph fp->kbddev = makedev(SCCDEV, SCCKBD_PORT); 423*56815Sralph break; 424*56815Sralph #endif 425*56815Sralph #if NDTOP > 0 426*56815Sralph case DS_MAXINE: 427*56815Sralph fp->KBDPutc = dtopKBDPutc; 428*56815Sralph fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT); 429*56815Sralph break; 430*56815Sralph #endif 431*56815Sralph default: 432*56815Sralph printf("Can't configure keyboard/mouse\n"); 433*56815Sralph return (0); 434*56815Sralph }; 435*56815Sralph 436*56815Sralph /* 437*56815Sralph * Initialize the screen. 438*56815Sralph */ 439*56815Sralph bt431_init(fp->fr_addr + MFB_OFFSET_BT431); 440*56815Sralph 441*56815Sralph /* 442*56815Sralph * Initialize screen info. 443*56815Sralph */ 444*56815Sralph fp->fbu->scrInfo.max_row = 67; 445*56815Sralph fp->fbu->scrInfo.max_col = 80; 446*56815Sralph fp->fbu->scrInfo.max_x = 1280; 447*56815Sralph fp->fbu->scrInfo.max_y = 1024; 448*56815Sralph fp->fbu->scrInfo.max_cur_x = 1279; 449*56815Sralph fp->fbu->scrInfo.max_cur_y = 1023; 450*56815Sralph fp->fbu->scrInfo.version = 11; 451*56815Sralph fp->fbu->scrInfo.mthreshold = 4; 452*56815Sralph fp->fbu->scrInfo.mscale = 2; 453*56815Sralph fp->fbu->scrInfo.min_cur_x = 0; 454*56815Sralph fp->fbu->scrInfo.min_cur_y = 0; 455*56815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 456*56815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 457*56815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 458*56815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 459*56815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 460*56815Sralph 461*56815Sralph /* 462*56815Sralph * Initialize the color map, the screen, and the mouse. 463*56815Sralph */ 464*56815Sralph mfbInitColorMap(); 465*56815Sralph mfbScreenInit(); 466*56815Sralph fbScroll(fp); 467*56815Sralph 468*56815Sralph fp->initialized = 1; 469*56815Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 470*56815Sralph cn_tab.cn_fb = fp; 471*56815Sralph return (1); 472*56815Sralph } 473*56815Sralph 474*56815Sralph /* 475*56815Sralph * ---------------------------------------------------------------------------- 476*56815Sralph * 477*56815Sralph * mfbScreenInit -- 478*56815Sralph * 479*56815Sralph * Initialize the screen. 480*56815Sralph * 481*56815Sralph * Results: 482*56815Sralph * None. 483*56815Sralph * 484*56815Sralph * Side effects: 485*56815Sralph * The screen is initialized. 486*56815Sralph * 487*56815Sralph * ---------------------------------------------------------------------------- 488*56815Sralph */ 489*56815Sralph static void 490*56815Sralph mfbScreenInit() 491*56815Sralph { 492*56815Sralph register struct pmax_fb *fp = &mfbfb; 493*56815Sralph 494*56815Sralph /* 495*56815Sralph * Home the cursor. 496*56815Sralph * We want an LSI terminal emulation. We want the graphics 497*56815Sralph * terminal to scroll from the bottom. So start at the bottom. 498*56815Sralph */ 499*56815Sralph fp->row = 66; 500*56815Sralph fp->col = 0; 501*56815Sralph 502*56815Sralph /* 503*56815Sralph * Load the cursor with the default values 504*56815Sralph * 505*56815Sralph */ 506*56815Sralph mfbLoadCursor(defCursor); 507*56815Sralph } 508*56815Sralph 509*56815Sralph /* 510*56815Sralph * ---------------------------------------------------------------------------- 511*56815Sralph * 512*56815Sralph * RestoreCursorColor -- 513*56815Sralph * 514*56815Sralph * Routine to restore the color of the cursor. 515*56815Sralph * 516*56815Sralph * Results: 517*56815Sralph * None. 518*56815Sralph * 519*56815Sralph * Side effects: 520*56815Sralph * None. 521*56815Sralph * 522*56815Sralph * ---------------------------------------------------------------------------- 523*56815Sralph */ 524*56815Sralph static void 525*56815Sralph mfbRestoreCursorColor() 526*56815Sralph { 527*56815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 528*56815Sralph ColorMap cm; 529*56815Sralph register int i; 530*56815Sralph 531*56815Sralph cm.index = 8; 532*56815Sralph cm.Entry.red = cursor_RGB[0] << 8; 533*56815Sralph cm.Entry.green = cursor_RGB[1] << 8; 534*56815Sralph cm.Entry.blue = cursor_RGB[2] << 8; 535*56815Sralph mfbLoadColorMap(&cm); 536*56815Sralph cm.index = 9; 537*56815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 538*56815Sralph mfbLoadColorMap(&cm); 539*56815Sralph 540*56815Sralph regs->addr_ovly = cursor_RGB[3] >> 4; 541*56815Sralph MachEmptyWriteBuffer(); 542*56815Sralph regs->addr_ovly = cursor_RGB[4] >> 4; 543*56815Sralph MachEmptyWriteBuffer(); 544*56815Sralph regs->addr_ovly = cursor_RGB[5] >> 4; 545*56815Sralph MachEmptyWriteBuffer(); 546*56815Sralph } 547*56815Sralph 548*56815Sralph /* 549*56815Sralph * ---------------------------------------------------------------------------- 550*56815Sralph * 551*56815Sralph * CursorColor -- 552*56815Sralph * 553*56815Sralph * Set the color of the cursor. 554*56815Sralph * 555*56815Sralph * Results: 556*56815Sralph * None. 557*56815Sralph * 558*56815Sralph * Side effects: 559*56815Sralph * None. 560*56815Sralph * 561*56815Sralph * ---------------------------------------------------------------------------- 562*56815Sralph */ 563*56815Sralph static void 564*56815Sralph mfbCursorColor(color) 565*56815Sralph unsigned int color[]; 566*56815Sralph { 567*56815Sralph register int i, j; 568*56815Sralph 569*56815Sralph for (i = 0; i < 6; i++) 570*56815Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 571*56815Sralph 572*56815Sralph mfbRestoreCursorColor(); 573*56815Sralph } 574*56815Sralph 575*56815Sralph /* 576*56815Sralph *---------------------------------------------------------------------- 577*56815Sralph * 578*56815Sralph * PosCursor -- 579*56815Sralph * 580*56815Sralph * Postion the cursor. 581*56815Sralph * 582*56815Sralph * Results: 583*56815Sralph * None. 584*56815Sralph * 585*56815Sralph * Side effects: 586*56815Sralph * None. 587*56815Sralph * 588*56815Sralph *---------------------------------------------------------------------- 589*56815Sralph */ 590*56815Sralph void 591*56815Sralph mfbPosCursor(x, y) 592*56815Sralph register int x, y; 593*56815Sralph { 594*56815Sralph bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431); 595*56815Sralph register struct pmax_fb *fp = &mfbfb; 596*56815Sralph 597*56815Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 598*56815Sralph y = fp->fbu->scrInfo.max_cur_y; 599*56815Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 600*56815Sralph x = fp->fbu->scrInfo.max_cur_x; 601*56815Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 602*56815Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 603*56815Sralph 604*56815Sralph #define lo(v) ((v)&0xff) 605*56815Sralph #define hi(v) (((v)&0xf00)>>8) 606*56815Sralph 607*56815Sralph /* 608*56815Sralph * Cx = x + D + H - P 609*56815Sralph * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 610*56815Sralph * D = pixel skew between outdata and external data 611*56815Sralph * H = pixels between HSYNCH falling and active video 612*56815Sralph * 613*56815Sralph * Cy = y + V - 32 614*56815Sralph * V = scanlines between HSYNCH falling, two or more 615*56815Sralph * clocks after VSYNCH falling, and active video 616*56815Sralph */ 617*56815Sralph 618*56815Sralph bt431_write_reg(regs, lo(x + 360)); 619*56815Sralph BT431_WRITE_REG_AUTOI(regs, hi(x + 360)); 620*56815Sralph BT431_WRITE_REG_AUTOI(regs, lo(y + 36)); 621*56815Sralph BT431_WRITE_REG_AUTOI(regs, hi(y + 36)); 622*56815Sralph } 623*56815Sralph 624*56815Sralph /* 625*56815Sralph * ---------------------------------------------------------------------------- 626*56815Sralph * 627*56815Sralph * InitColorMap -- 628*56815Sralph * 629*56815Sralph * Initialize the color map. 630*56815Sralph * 631*56815Sralph * Results: 632*56815Sralph * None. 633*56815Sralph * 634*56815Sralph * Side effects: 635*56815Sralph * The colormap is initialized appropriately. 636*56815Sralph * 637*56815Sralph * ---------------------------------------------------------------------------- 638*56815Sralph */ 639*56815Sralph static void 640*56815Sralph mfbInitColorMap() 641*56815Sralph { 642*56815Sralph ColorMap cm; 643*56815Sralph register int i; 644*56815Sralph 645*56815Sralph cm.index = 0; 646*56815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 647*56815Sralph mfbLoadColorMap(&cm); 648*56815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 649*56815Sralph for (i = 1; i < 16; i++) { 650*56815Sralph cm.index = i; 651*56815Sralph mfbLoadColorMap(&cm); 652*56815Sralph } 653*56815Sralph 654*56815Sralph for (i = 0; i < 3; i++) { 655*56815Sralph cursor_RGB[i] = 0x00; 656*56815Sralph cursor_RGB[i + 3] = 0xff; 657*56815Sralph } 658*56815Sralph mfbRestoreCursorColor(); 659*56815Sralph } 660*56815Sralph 661*56815Sralph /* 662*56815Sralph * ---------------------------------------------------------------------------- 663*56815Sralph * 664*56815Sralph * LoadColorMap -- 665*56815Sralph * 666*56815Sralph * Load the color map. 667*56815Sralph * 668*56815Sralph * Results: 669*56815Sralph * None. 670*56815Sralph * 671*56815Sralph * Side effects: 672*56815Sralph * The color map is loaded. 673*56815Sralph * 674*56815Sralph * ---------------------------------------------------------------------------- 675*56815Sralph */ 676*56815Sralph static void 677*56815Sralph mfbLoadColorMap(ptr) 678*56815Sralph ColorMap *ptr; 679*56815Sralph { 680*56815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 681*56815Sralph 682*56815Sralph if (ptr->index > 15) 683*56815Sralph return; 684*56815Sralph 685*56815Sralph BT455_SELECT_ENTRY(regs, ptr->index); 686*56815Sralph regs->addr_cmap_data = ptr->Entry.red >> 12; 687*56815Sralph MachEmptyWriteBuffer(); 688*56815Sralph regs->addr_cmap_data = ptr->Entry.green >> 12; 689*56815Sralph MachEmptyWriteBuffer(); 690*56815Sralph regs->addr_cmap_data = ptr->Entry.blue >> 12; 691*56815Sralph MachEmptyWriteBuffer(); 692*56815Sralph } 693*56815Sralph 694*56815Sralph /* 695*56815Sralph * Video on/off state. 696*56815Sralph */ 697*56815Sralph static struct vstate { 698*56815Sralph u_char color0[6]; /* saved color map entry zero */ 699*56815Sralph u_char off; /* TRUE if display is off */ 700*56815Sralph } vstate; 701*56815Sralph 702*56815Sralph /* 703*56815Sralph * ---------------------------------------------------------------------------- 704*56815Sralph * 705*56815Sralph * bt455_video_on 706*56815Sralph * 707*56815Sralph * Enable the video display. 708*56815Sralph * 709*56815Sralph * Results: 710*56815Sralph * None. 711*56815Sralph * 712*56815Sralph * Side effects: 713*56815Sralph * The display is enabled. 714*56815Sralph * 715*56815Sralph * ---------------------------------------------------------------------------- 716*56815Sralph */ 717*56815Sralph static void 718*56815Sralph bt455_video_on() 719*56815Sralph { 720*56815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 721*56815Sralph 722*56815Sralph if (!vstate.off) 723*56815Sralph return; 724*56815Sralph 725*56815Sralph /* restore old color map entry zero */ 726*56815Sralph BT455_SELECT_ENTRY(regs, 0); 727*56815Sralph regs->addr_cmap_data = vstate.color0[0]; 728*56815Sralph MachEmptyWriteBuffer(); 729*56815Sralph regs->addr_cmap_data = vstate.color0[1]; 730*56815Sralph MachEmptyWriteBuffer(); 731*56815Sralph regs->addr_cmap_data = vstate.color0[2]; 732*56815Sralph MachEmptyWriteBuffer(); 733*56815Sralph regs->addr_cmap_data = vstate.color0[3]; 734*56815Sralph MachEmptyWriteBuffer(); 735*56815Sralph regs->addr_cmap_data = vstate.color0[4]; 736*56815Sralph MachEmptyWriteBuffer(); 737*56815Sralph regs->addr_cmap_data = vstate.color0[5]; 738*56815Sralph MachEmptyWriteBuffer(); 739*56815Sralph 740*56815Sralph vstate.off = 0; 741*56815Sralph } 742*56815Sralph 743*56815Sralph /* 744*56815Sralph * ---------------------------------------------------------------------------- 745*56815Sralph * 746*56815Sralph * bt455_video_off 747*56815Sralph * 748*56815Sralph * Disable the video display. 749*56815Sralph * 750*56815Sralph * Results: 751*56815Sralph * None. 752*56815Sralph * 753*56815Sralph * Side effects: 754*56815Sralph * The display is disabled. 755*56815Sralph * 756*56815Sralph * ---------------------------------------------------------------------------- 757*56815Sralph */ 758*56815Sralph static void 759*56815Sralph bt455_video_off() 760*56815Sralph { 761*56815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 762*56815Sralph ColorMap cm; 763*56815Sralph 764*56815Sralph if (vstate.off) 765*56815Sralph return; 766*56815Sralph 767*56815Sralph /* save old color map entry zero */ 768*56815Sralph BT455_SELECT_ENTRY(regs, 0); 769*56815Sralph vstate.color0[0] = regs->addr_cmap_data; 770*56815Sralph vstate.color0[1] = regs->addr_cmap_data; 771*56815Sralph vstate.color0[2] = regs->addr_cmap_data; 772*56815Sralph vstate.color0[3] = regs->addr_cmap_data; 773*56815Sralph vstate.color0[4] = regs->addr_cmap_data; 774*56815Sralph vstate.color0[5] = regs->addr_cmap_data; 775*56815Sralph 776*56815Sralph /* set color map entry zero to zero */ 777*56815Sralph cm.index = 0; 778*56815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 779*56815Sralph mfbLoadColorMap(&cm); 780*56815Sralph cm.index = 1; 781*56815Sralph mfbLoadColorMap(&cm); 782*56815Sralph 783*56815Sralph vstate.off = 1; 784*56815Sralph } 785*56815Sralph 786*56815Sralph /* 787*56815Sralph * mfb keyboard and mouse input. Just punt to the generic ones in fb.c 788*56815Sralph */ 789*56815Sralph void 790*56815Sralph mfbKbdEvent(ch) 791*56815Sralph int ch; 792*56815Sralph { 793*56815Sralph fbKbdEvent(ch, &mfbfb); 794*56815Sralph } 795*56815Sralph 796*56815Sralph void 797*56815Sralph mfbMouseEvent(newRepPtr) 798*56815Sralph MouseReport *newRepPtr; 799*56815Sralph { 800*56815Sralph fbMouseEvent(newRepPtr, &mfbfb); 801*56815Sralph } 802*56815Sralph 803*56815Sralph void 804*56815Sralph mfbMouseButtons(newRepPtr) 805*56815Sralph MouseReport *newRepPtr; 806*56815Sralph { 807*56815Sralph fbMouseButtons(newRepPtr, &mfbfb); 808*56815Sralph } 809*56815Sralph 810*56815Sralph /* 811*56815Sralph * Configure the mouse and keyboard based on machine type 812*56815Sralph */ 813*56815Sralph static void 814*56815Sralph mfbConfigMouse() 815*56815Sralph { 816*56815Sralph int s; 817*56815Sralph 818*56815Sralph s = spltty(); 819*56815Sralph switch (pmax_boardtype) { 820*56815Sralph #if NDC > 0 821*56815Sralph case DS_3MAX: 822*56815Sralph dcDivertXInput = mfbKbdEvent; 823*56815Sralph dcMouseEvent = mfbMouseEvent; 824*56815Sralph dcMouseButtons = mfbMouseButtons; 825*56815Sralph break; 826*56815Sralph #endif 827*56815Sralph #if NSCC > 1 828*56815Sralph case DS_3MIN: 829*56815Sralph sccDivertXInput = mfbKbdEvent; 830*56815Sralph sccMouseEvent = mfbMouseEvent; 831*56815Sralph sccMouseButtons = mfbMouseButtons; 832*56815Sralph break; 833*56815Sralph #endif 834*56815Sralph #if NDTOP > 0 835*56815Sralph case DS_MAXINE: 836*56815Sralph dtopDivertXInput = mfbKbdEvent; 837*56815Sralph dtopMouseEvent = mfbMouseEvent; 838*56815Sralph dtopMouseButtons = mfbMouseButtons; 839*56815Sralph break; 840*56815Sralph #endif 841*56815Sralph default: 842*56815Sralph printf("Can't configure mouse/keyboard\n"); 843*56815Sralph }; 844*56815Sralph splx(s); 845*56815Sralph } 846*56815Sralph 847*56815Sralph /* 848*56815Sralph * and deconfigure them 849*56815Sralph */ 850*56815Sralph static void 851*56815Sralph mfbDeconfigMouse() 852*56815Sralph { 853*56815Sralph int s; 854*56815Sralph 855*56815Sralph s = spltty(); 856*56815Sralph switch (pmax_boardtype) { 857*56815Sralph #if NDC > 0 858*56815Sralph case DS_3MAX: 859*56815Sralph dcDivertXInput = (void (*)())0; 860*56815Sralph dcMouseEvent = (void (*)())0; 861*56815Sralph dcMouseButtons = (void (*)())0; 862*56815Sralph break; 863*56815Sralph #endif 864*56815Sralph #if NSCC > 1 865*56815Sralph case DS_3MIN: 866*56815Sralph sccDivertXInput = (void (*)())0; 867*56815Sralph sccMouseEvent = (void (*)())0; 868*56815Sralph sccMouseButtons = (void (*)())0; 869*56815Sralph break; 870*56815Sralph #endif 871*56815Sralph #if NDTOP > 0 872*56815Sralph case DS_MAXINE: 873*56815Sralph dtopDivertXInput = (void (*)())0; 874*56815Sralph dtopMouseEvent = (void (*)())0; 875*56815Sralph dtopMouseButtons = (void (*)())0; 876*56815Sralph break; 877*56815Sralph #endif 878*56815Sralph default: 879*56815Sralph printf("Can't deconfigure mouse/keyboard\n"); 880*56815Sralph }; 881*56815Sralph } 882*56815Sralph 883*56815Sralph /* 884*56815Sralph * Generic register access 885*56815Sralph */ 886*56815Sralph static void 887*56815Sralph bt431_select_reg(regs, regno) 888*56815Sralph bt431_regmap_t *regs; 889*56815Sralph { 890*56815Sralph regs->addr_lo = SET_VALUE(regno & 0xff); 891*56815Sralph regs->addr_hi = SET_VALUE((regno >> 8) & 0xff); 892*56815Sralph MachEmptyWriteBuffer(); 893*56815Sralph } 894*56815Sralph 895*56815Sralph static void 896*56815Sralph bt431_write_reg(regs, regno, val) 897*56815Sralph bt431_regmap_t *regs; 898*56815Sralph { 899*56815Sralph bt431_select_reg(regs, regno); 900*56815Sralph regs->addr_reg = SET_VALUE(val); 901*56815Sralph MachEmptyWriteBuffer(); 902*56815Sralph } 903*56815Sralph 904*56815Sralph static u_char 905*56815Sralph bt431_read_reg(regs, regno) 906*56815Sralph bt431_regmap_t *regs; 907*56815Sralph { 908*56815Sralph bt431_select_reg(regs, regno); 909*56815Sralph return (GET_VALUE(regs->addr_reg)); 910*56815Sralph } 911*56815Sralph 912*56815Sralph static void 913*56815Sralph bt431_init(regs) 914*56815Sralph bt431_regmap_t *regs; 915*56815Sralph { 916*56815Sralph register int i; 917*56815Sralph 918*56815Sralph /* use 4:1 input mux */ 919*56815Sralph bt431_write_reg(regs, BT431_REG_CMD, 920*56815Sralph BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS| 921*56815Sralph BT431_CMD_4_1_MUX|BT431_CMD_THICK_1); 922*56815Sralph 923*56815Sralph /* home cursor */ 924*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 925*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 926*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 927*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 928*56815Sralph 929*56815Sralph /* no crosshair window */ 930*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 931*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 932*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 933*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 934*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 935*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 936*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 937*56815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 938*56815Sralph } 939*56815Sralph #endif /* NMFB */ 940