156815Sralph /*- 256815Sralph * Copyright (c) 1992 The Regents of the University of California. 356815Sralph * All rights reserved. 456815Sralph * 556815Sralph * This code is derived from software contributed to Berkeley by 656815Sralph * Ralph Campbell and Rick Macklem. 756815Sralph * 856815Sralph * %sccs.include.redist.c% 956815Sralph * 10*58793Sralph * @(#)mfb.c 7.3 (Berkeley) 03/23/93 1156815Sralph */ 1256815Sralph 1356815Sralph /* 1456815Sralph * Mach Operating System 1556815Sralph * Copyright (c) 1991,1990,1989 Carnegie Mellon University 1656815Sralph * All Rights Reserved. 1756815Sralph * 1856815Sralph * Permission to use, copy, modify and distribute this software and its 1956815Sralph * documentation is hereby granted, provided that both the copyright 2056815Sralph * notice and this permission notice appear in all copies of the 2156815Sralph * software, derivative works or modified versions, and any portions 2256815Sralph * thereof, and that both notices appear in supporting documentation. 2356815Sralph * 2456815Sralph * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 2556815Sralph * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 2656815Sralph * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 2756815Sralph * 2856815Sralph * Carnegie Mellon requests users of this software to return to 2956815Sralph * 3056815Sralph * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 3156815Sralph * School of Computer Science 3256815Sralph * Carnegie Mellon University 3356815Sralph * Pittsburgh PA 15213-3890 3456815Sralph * 3556815Sralph * any improvements or extensions that they make and grant Carnegie the 3656815Sralph * rights to redistribute these changes. 3756815Sralph */ 3856815Sralph /* 3956815Sralph * devGraphics.c -- 4056815Sralph * 4156815Sralph * This file contains machine-dependent routines for the graphics device. 4256815Sralph * 4356815Sralph * Copyright (C) 1989 Digital Equipment Corporation. 4456815Sralph * Permission to use, copy, modify, and distribute this software and 4556815Sralph * its documentation for any purpose and without fee is hereby granted, 4656815Sralph * provided that the above copyright notice appears in all copies. 4756815Sralph * Digital Equipment Corporation makes no representations about the 4856815Sralph * suitability of this software for any purpose. It is provided "as is" 4956815Sralph * without express or implied warranty. 5056815Sralph * 5156815Sralph * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 5256815Sralph * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 5356815Sralph */ 5456815Sralph 5556815Sralph #include <mfb.h> 5656815Sralph #if NMFB > 0 5756815Sralph #include <sys/param.h> 5856815Sralph #include <sys/time.h> 5956815Sralph #include <sys/kernel.h> 6056815Sralph #include <sys/ioctl.h> 6156815Sralph #include <sys/file.h> 6256815Sralph #include <sys/errno.h> 6356815Sralph #include <sys/proc.h> 6456815Sralph #include <sys/mman.h> 6556815Sralph 6656815Sralph #include <vm/vm.h> 6756815Sralph 6856815Sralph #include <machine/machConst.h> 6956815Sralph #include <machine/pmioctl.h> 7056815Sralph 7156815Sralph #include <pmax/pmax/cons.h> 7256815Sralph #include <pmax/pmax/pmaxtype.h> 7356815Sralph 7456815Sralph #include <pmax/dev/device.h> 7556815Sralph #include <pmax/dev/mfbreg.h> 7656815Sralph #include <pmax/dev/fbreg.h> 7756815Sralph 7856815Sralph #include <dc.h> 7956815Sralph #include <dtop.h> 8056815Sralph #include <scc.h> 8156815Sralph 8256815Sralph /* 8356815Sralph * These need to be mapped into user space. 8456815Sralph */ 8556815Sralph struct fbuaccess mfbu; 8656815Sralph struct pmax_fb mfbfb; 8756815Sralph 8856815Sralph /* 8956815Sralph * Forward references. 9056815Sralph */ 9156815Sralph extern void fbScroll(); 9256815Sralph 9356815Sralph static void mfbScreenInit(); 9456815Sralph static void mfbLoadCursor(); 9556815Sralph static void mfbRestoreCursorColor(); 9656815Sralph static void mfbCursorColor(); 9756815Sralph void mfbPosCursor(); 9856815Sralph static void mfbInitColorMap(); 9956815Sralph static void mfbLoadColorMap(); 10056815Sralph static void mfbConfigMouse(), mfbDeconfigMouse(); 10156815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg(); 10256815Sralph static void bt431_write_reg(), bt431_init(); 10356815Sralph static u_char bt431_read_reg(); 10456815Sralph 10556815Sralph extern void fbKbdEvent(), fbMouseEvent(), fbMouseButtons(); 10656815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons(); 10756815Sralph #if NDC > 0 10856815Sralph extern void (*dcDivertXInput)(); 10956815Sralph extern void (*dcMouseEvent)(); 11056815Sralph extern void (*dcMouseButtons)(); 11156815Sralph #endif 11256815Sralph #if NSCC > 0 11356815Sralph extern void (*sccDivertXInput)(); 11456815Sralph extern void (*sccMouseEvent)(); 11556815Sralph extern void (*sccMouseButtons)(); 11656815Sralph #endif 11756815Sralph #if NDTOP > 0 11856815Sralph extern void (*dtopDivertXInput)(); 11956815Sralph extern void (*dtopMouseEvent)(); 12056815Sralph extern void (*dtopMouseButtons)(); 12156815Sralph #endif 12256815Sralph extern int pmax_boardtype; 12356815Sralph extern u_short defCursor[32]; 12456815Sralph extern struct consdev cn_tab; 12556815Sralph 12656815Sralph int mfbprobe(); 12756815Sralph struct driver mfbdriver = { 12856815Sralph "mfb", mfbprobe, 0, 0, 12956815Sralph }; 13056815Sralph 13156815Sralph #define MFB_OFFSET_VRAM 0x200000 /* from module's base */ 13256815Sralph #define MFB_OFFSET_BT431 0x180000 /* Bt431 registers */ 13356815Sralph #define MFB_OFFSET_BT455 0x100000 /* Bt455 registers */ 13456815Sralph #define MFB_OFFSET_IREQ 0x080000 /* Interrupt req. control */ 13556815Sralph #define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */ 13656815Sralph 13756815Sralph /* 13856815Sralph * Test to see if device is present. 13956815Sralph * Return true if found and initialized ok. 14056815Sralph */ 14156815Sralph /*ARGSUSED*/ 14256815Sralph mfbprobe(cp) 14356815Sralph register struct pmax_ctlr *cp; 14456815Sralph { 14556815Sralph register struct pmax_fb *fp = &mfbfb; 14656815Sralph 14756815Sralph if (!fp->initialized && !mfbinit(cp->pmax_addr)) 14856815Sralph return (0); 14956815Sralph printf("mfb0 (mono display)\n"); 15056815Sralph return (1); 15156815Sralph } 15256815Sralph 15356815Sralph /*ARGSUSED*/ 15456815Sralph mfbopen(dev, flag) 15556815Sralph dev_t dev; 15656815Sralph int flag; 15756815Sralph { 15856815Sralph register struct pmax_fb *fp = &mfbfb; 15956815Sralph int s; 16056815Sralph 16156815Sralph if (!fp->initialized) 16256815Sralph return (ENXIO); 16356815Sralph if (fp->GraphicsOpen) 16456815Sralph return (EBUSY); 16556815Sralph 16656815Sralph fp->GraphicsOpen = 1; 167*58793Sralph mfbInitColorMap(1); 16856815Sralph /* 16956815Sralph * Set up event queue for later 17056815Sralph */ 17156815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 17256815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 17356815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 17456815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 17556815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 17656815Sralph mfbConfigMouse(); 17756815Sralph return (0); 17856815Sralph } 17956815Sralph 18056815Sralph /*ARGSUSED*/ 18156815Sralph mfbclose(dev, flag) 18256815Sralph dev_t dev; 18356815Sralph int flag; 18456815Sralph { 18556815Sralph register struct pmax_fb *fp = &mfbfb; 18656815Sralph int s; 18756815Sralph 18856815Sralph if (!fp->GraphicsOpen) 18956815Sralph return (EBADF); 19056815Sralph 19156815Sralph fp->GraphicsOpen = 0; 192*58793Sralph mfbInitColorMap(0); 19356815Sralph mfbDeconfigMouse(); 19456815Sralph mfbScreenInit(); 19556815Sralph vmUserUnmap(); 196*58793Sralph bzero((caddr_t)fp->fr_addr, 2048 * 1024); 19756815Sralph mfbPosCursor(fp->col * 8, fp->row * 15); 19856815Sralph return (0); 19956815Sralph } 20056815Sralph 20156815Sralph /*ARGSUSED*/ 20256815Sralph mfbioctl(dev, cmd, data, flag) 20356815Sralph dev_t dev; 20456815Sralph caddr_t data; 20556815Sralph { 20656815Sralph register struct pmax_fb *fp = &mfbfb; 20756815Sralph int s; 20856815Sralph 20956815Sralph switch (cmd) { 21056815Sralph case QIOCGINFO: 21156815Sralph { 21256815Sralph caddr_t addr; 21356815Sralph extern caddr_t vmUserMap(); 21456815Sralph 21556815Sralph /* 21656815Sralph * Map the all the data the user needs access to into 21756815Sralph * user space. 21856815Sralph */ 21956815Sralph addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu); 22056815Sralph if (addr == (caddr_t)0) 22156815Sralph goto mapError; 22256815Sralph *(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo; 22356815Sralph fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events; 22456815Sralph fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs; 22556815Sralph fp->fbu->scrInfo.planemask = (char *)0; 22656815Sralph /* 22756815Sralph * Map the frame buffer into the user's address space. 22856815Sralph */ 229*58793Sralph addr = vmUserMap(2048 * 1024, (unsigned)fp->fr_addr); 23056815Sralph if (addr == (caddr_t)0) 23156815Sralph goto mapError; 23256815Sralph fp->fbu->scrInfo.bitmap = (char *)addr; 23356815Sralph break; 23456815Sralph 23556815Sralph mapError: 23656815Sralph vmUserUnmap(); 23756815Sralph printf("Cannot map shared data structures\n"); 23856815Sralph return (EIO); 23956815Sralph } 24056815Sralph 24156815Sralph case QIOCPMSTATE: 24256815Sralph /* 24356815Sralph * Set mouse state. 24456815Sralph */ 24556815Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 24656815Sralph mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 24756815Sralph break; 24856815Sralph 24956815Sralph case QIOCINIT: 25056815Sralph /* 25156815Sralph * Initialize the screen. 25256815Sralph */ 25356815Sralph mfbScreenInit(); 25456815Sralph break; 25556815Sralph 25656815Sralph case QIOCKPCMD: 25756815Sralph { 25856815Sralph pmKpCmd *kpCmdPtr; 25956815Sralph unsigned char *cp; 26056815Sralph 26156815Sralph kpCmdPtr = (pmKpCmd *)data; 26256815Sralph if (kpCmdPtr->nbytes == 0) 26356815Sralph kpCmdPtr->cmd |= 0x80; 26456815Sralph if (!fp->GraphicsOpen) 26556815Sralph kpCmdPtr->cmd |= 1; 26656815Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 26756815Sralph cp = &kpCmdPtr->par[0]; 26856815Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 26956815Sralph if (kpCmdPtr->nbytes == 1) 27056815Sralph *cp |= 0x80; 27156815Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 27256815Sralph } 27356815Sralph } 27456815Sralph break; 27556815Sralph 27656815Sralph case QIOCADDR: 27756815Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 27856815Sralph break; 27956815Sralph 28056815Sralph case QIOWCURSOR: 28156815Sralph mfbLoadCursor((unsigned short *)data); 28256815Sralph break; 28356815Sralph 28456815Sralph case QIOWCURSORCOLOR: 28556815Sralph mfbCursorColor((unsigned int *)data); 28656815Sralph break; 28756815Sralph 28856815Sralph case QIOSETCMAP: 289*58793Sralph #ifdef notdef 29056815Sralph mfbLoadColorMap((ColorMap *)data); 291*58793Sralph #endif 29256815Sralph break; 29356815Sralph 29456815Sralph case QIOKERNLOOP: 29556815Sralph mfbConfigMouse(); 29656815Sralph break; 29756815Sralph 29856815Sralph case QIOKERNUNLOOP: 29956815Sralph mfbDeconfigMouse(); 30056815Sralph break; 30156815Sralph 30256815Sralph case QIOVIDEOON: 30356815Sralph bt455_video_on(); 30456815Sralph break; 30556815Sralph 30656815Sralph case QIOVIDEOOFF: 30756815Sralph bt455_video_off(); 30856815Sralph break; 30956815Sralph 31056815Sralph default: 31156815Sralph printf("mfb0: Unknown ioctl command %x\n", cmd); 31256815Sralph return (EINVAL); 31356815Sralph } 31456815Sralph return (0); 31556815Sralph } 31656815Sralph 31756815Sralph mfbselect(dev, flag, p) 31856815Sralph dev_t dev; 31956815Sralph int flag; 32056815Sralph struct proc *p; 32156815Sralph { 32256815Sralph struct pmax_fb *fp = &mfbfb; 32356815Sralph 32456815Sralph switch (flag) { 32556815Sralph case FREAD: 32656815Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 32756815Sralph return (1); 32856815Sralph selrecord(p, &fp->selp); 32956815Sralph break; 33056815Sralph } 33156815Sralph 33256815Sralph return (0); 33356815Sralph } 33456815Sralph 33556815Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 33656815Sralph 33756815Sralph /* 33856815Sralph * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit 33956815Sralph * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding 34056815Sralph * registers for these two chips live in adjacent bytes of the shorts that 34156815Sralph * are defined in bt431_regmap_t. 34256815Sralph */ 34356815Sralph static void 34456815Sralph mfbLoadCursor(cursor) 34556815Sralph u_short *cursor; 34656815Sralph { 34756815Sralph register int i, j, k, pos; 34856815Sralph register u_short ap, bp, out; 34956815Sralph register bt431_regmap_t *regs; 35056815Sralph 351*58793Sralph regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr + 352*58793Sralph MFB_OFFSET_BT431); 35356815Sralph /* 35456815Sralph * Fill in the cursor sprite using the A and B planes, as provided 35556815Sralph * for the pmax. 35656815Sralph * XXX This will have to change when the X server knows that this 357*58793Sralph * is not a pmax display. (ie. Not the Xcfbpmax server.) 35856815Sralph */ 35956815Sralph pos = 0; 36056815Sralph bt431_select_reg(regs, BT431_REG_CRAM_BASE); 36156815Sralph for (k = 0; k < 16; k++) { 36256815Sralph ap = *cursor; 36356815Sralph bp = *(cursor + 16); 36456815Sralph j = 0; 36556815Sralph while (j < 2) { 36656815Sralph out = 0; 36756815Sralph for (i = 0; i < 8; i++) { 368*58793Sralph out = (out << 1) | ((bp & 0x1) << 8) | 369*58793Sralph (ap & 0x1); 37056815Sralph ap >>= 1; 37156815Sralph bp >>= 1; 37256815Sralph } 37356815Sralph BT431_WRITE_CMAP_AUTOI(regs, out); 37456815Sralph pos++; 37556815Sralph j++; 37656815Sralph } 37756815Sralph while (j < 8) { 37856815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 37956815Sralph pos++; 38056815Sralph j++; 38156815Sralph } 38256815Sralph cursor++; 38356815Sralph } 38456815Sralph while (pos < 512) { 38556815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 38656815Sralph pos++; 38756815Sralph } 38856815Sralph } 38956815Sralph 39056815Sralph /* 39156815Sralph * Initialization 39256815Sralph */ 39356815Sralph int 39456815Sralph mfbinit(cp) 39556815Sralph char *cp; 39656815Sralph { 39756815Sralph register struct pmax_fb *fp = &mfbfb; 39856815Sralph 39956815Sralph /* check for no frame buffer */ 40056815Sralph if (badaddr(cp, 4)) 40156815Sralph return (0); 40256815Sralph 403*58793Sralph fp->isMono = 0; 404*58793Sralph fp->fr_addr = cp + MFB_OFFSET_VRAM; 405*58793Sralph fp->fr_chipaddr = cp; 40657234Sralph /* 40757234Sralph * Must be in Uncached space or the Xserver sees a stale version of 40857234Sralph * the event queue and acts totally wacko. I don't understand this, 40957234Sralph * since the R3000 uses a physical address cache? 41057234Sralph */ 41157234Sralph fp->fbu = (struct fbuaccess *) 41257234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu)); 41356815Sralph fp->posCursor = mfbPosCursor; 41457234Sralph if (tb_kbdmouseconfig(fp)) 41556815Sralph return (0); 41656815Sralph 41756815Sralph /* 41856815Sralph * Initialize the screen. 41956815Sralph */ 420*58793Sralph bt431_init(fp->fr_chipaddr + MFB_OFFSET_BT431); 42156815Sralph 42256815Sralph /* 42356815Sralph * Initialize screen info. 42456815Sralph */ 42556815Sralph fp->fbu->scrInfo.max_row = 67; 42656815Sralph fp->fbu->scrInfo.max_col = 80; 42756815Sralph fp->fbu->scrInfo.max_x = 1280; 42856815Sralph fp->fbu->scrInfo.max_y = 1024; 42956815Sralph fp->fbu->scrInfo.max_cur_x = 1279; 43056815Sralph fp->fbu->scrInfo.max_cur_y = 1023; 43156815Sralph fp->fbu->scrInfo.version = 11; 43256815Sralph fp->fbu->scrInfo.mthreshold = 4; 43356815Sralph fp->fbu->scrInfo.mscale = 2; 43456815Sralph fp->fbu->scrInfo.min_cur_x = 0; 43556815Sralph fp->fbu->scrInfo.min_cur_y = 0; 43656815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 43756815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 43856815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 43956815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 44056815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 44156815Sralph 44256815Sralph /* 44356815Sralph * Initialize the color map, the screen, and the mouse. 44456815Sralph */ 445*58793Sralph mfbInitColorMap(0); 44656815Sralph mfbScreenInit(); 44756815Sralph fbScroll(fp); 44856815Sralph 44956815Sralph fp->initialized = 1; 45056815Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 45156815Sralph cn_tab.cn_fb = fp; 45256815Sralph return (1); 45356815Sralph } 45456815Sralph 45556815Sralph /* 45656815Sralph * ---------------------------------------------------------------------------- 45756815Sralph * 45856815Sralph * mfbScreenInit -- 45956815Sralph * 46056815Sralph * Initialize the screen. 46156815Sralph * 46256815Sralph * Results: 46356815Sralph * None. 46456815Sralph * 46556815Sralph * Side effects: 46656815Sralph * The screen is initialized. 46756815Sralph * 46856815Sralph * ---------------------------------------------------------------------------- 46956815Sralph */ 47056815Sralph static void 47156815Sralph mfbScreenInit() 47256815Sralph { 47356815Sralph register struct pmax_fb *fp = &mfbfb; 47456815Sralph 47556815Sralph /* 47656815Sralph * Home the cursor. 47756815Sralph * We want an LSI terminal emulation. We want the graphics 47856815Sralph * terminal to scroll from the bottom. So start at the bottom. 47956815Sralph */ 48056815Sralph fp->row = 66; 48156815Sralph fp->col = 0; 48256815Sralph 48356815Sralph /* 48456815Sralph * Load the cursor with the default values 48556815Sralph * 48656815Sralph */ 48756815Sralph mfbLoadCursor(defCursor); 48856815Sralph } 48956815Sralph 49056815Sralph /* 49156815Sralph * ---------------------------------------------------------------------------- 49256815Sralph * 49356815Sralph * RestoreCursorColor -- 49456815Sralph * 49556815Sralph * Routine to restore the color of the cursor. 49656815Sralph * 49756815Sralph * Results: 49856815Sralph * None. 49956815Sralph * 50056815Sralph * Side effects: 50156815Sralph * None. 50256815Sralph * 50356815Sralph * ---------------------------------------------------------------------------- 50456815Sralph */ 50556815Sralph static void 50656815Sralph mfbRestoreCursorColor() 50756815Sralph { 508*58793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 509*58793Sralph MFB_OFFSET_BT455); 51056815Sralph ColorMap cm; 511*58793Sralph u_char fg; 51256815Sralph 513*58793Sralph if (cursor_RGB[0] || cursor_RGB[1] || cursor_RGB[2]) 514*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 515*58793Sralph else 516*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 51756815Sralph cm.index = 8; 51856815Sralph mfbLoadColorMap(&cm); 51956815Sralph cm.index = 9; 52056815Sralph mfbLoadColorMap(&cm); 52156815Sralph 522*58793Sralph if (cursor_RGB[3] || cursor_RGB[4] || cursor_RGB[5]) 523*58793Sralph fg = 0xf; 524*58793Sralph else 525*58793Sralph fg = 0; 526*58793Sralph regs->addr_ovly = fg; 52756815Sralph MachEmptyWriteBuffer(); 528*58793Sralph regs->addr_ovly = fg; 52956815Sralph MachEmptyWriteBuffer(); 530*58793Sralph regs->addr_ovly = fg; 53156815Sralph MachEmptyWriteBuffer(); 53256815Sralph } 53356815Sralph 53456815Sralph /* 53556815Sralph * ---------------------------------------------------------------------------- 53656815Sralph * 53756815Sralph * CursorColor -- 53856815Sralph * 53956815Sralph * Set the color of the cursor. 54056815Sralph * 54156815Sralph * Results: 54256815Sralph * None. 54356815Sralph * 54456815Sralph * Side effects: 54556815Sralph * None. 54656815Sralph * 54756815Sralph * ---------------------------------------------------------------------------- 54856815Sralph */ 54956815Sralph static void 55056815Sralph mfbCursorColor(color) 55156815Sralph unsigned int color[]; 55256815Sralph { 55356815Sralph register int i, j; 55456815Sralph 55556815Sralph for (i = 0; i < 6; i++) 55656815Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 55756815Sralph 55856815Sralph mfbRestoreCursorColor(); 55956815Sralph } 56056815Sralph 56156815Sralph /* 56256815Sralph *---------------------------------------------------------------------- 56356815Sralph * 56456815Sralph * PosCursor -- 56556815Sralph * 56656815Sralph * Postion the cursor. 56756815Sralph * 56856815Sralph * Results: 56956815Sralph * None. 57056815Sralph * 57156815Sralph * Side effects: 57256815Sralph * None. 57356815Sralph * 57456815Sralph *---------------------------------------------------------------------- 57556815Sralph */ 57656815Sralph void 57756815Sralph mfbPosCursor(x, y) 57856815Sralph register int x, y; 57956815Sralph { 580*58793Sralph bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr + 581*58793Sralph MFB_OFFSET_BT431); 58256815Sralph register struct pmax_fb *fp = &mfbfb; 58356815Sralph 58456815Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 58556815Sralph y = fp->fbu->scrInfo.max_cur_y; 58656815Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 58756815Sralph x = fp->fbu->scrInfo.max_cur_x; 58856815Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 58956815Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 59056815Sralph 59156815Sralph #define lo(v) ((v)&0xff) 59256815Sralph #define hi(v) (((v)&0xf00)>>8) 59356815Sralph 59456815Sralph /* 59556815Sralph * Cx = x + D + H - P 59656815Sralph * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 59756815Sralph * D = pixel skew between outdata and external data 59856815Sralph * H = pixels between HSYNCH falling and active video 59956815Sralph * 60056815Sralph * Cy = y + V - 32 60156815Sralph * V = scanlines between HSYNCH falling, two or more 60256815Sralph * clocks after VSYNCH falling, and active video 60356815Sralph */ 60456815Sralph 605*58793Sralph bt431_write_reg(regs, BT431_REG_CXLO, lo(x + 360)); 60656815Sralph BT431_WRITE_REG_AUTOI(regs, hi(x + 360)); 60756815Sralph BT431_WRITE_REG_AUTOI(regs, lo(y + 36)); 60856815Sralph BT431_WRITE_REG_AUTOI(regs, hi(y + 36)); 60956815Sralph } 61056815Sralph 61156815Sralph /* 61256815Sralph * ---------------------------------------------------------------------------- 61356815Sralph * 61456815Sralph * InitColorMap -- 61556815Sralph * 61656815Sralph * Initialize the color map. 61756815Sralph * 61856815Sralph * Results: 61956815Sralph * None. 62056815Sralph * 62156815Sralph * Side effects: 62256815Sralph * The colormap is initialized appropriately. 62356815Sralph * 62456815Sralph * ---------------------------------------------------------------------------- 62556815Sralph */ 62656815Sralph static void 627*58793Sralph mfbInitColorMap(blackpix) 628*58793Sralph int blackpix; 62956815Sralph { 63056815Sralph ColorMap cm; 63156815Sralph register int i; 63256815Sralph 63356815Sralph cm.index = 0; 634*58793Sralph if (blackpix) 635*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 636*58793Sralph else 637*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 63856815Sralph mfbLoadColorMap(&cm); 639*58793Sralph if (blackpix) 640*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 641*58793Sralph else 642*58793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 64356815Sralph for (i = 1; i < 16; i++) { 64456815Sralph cm.index = i; 64556815Sralph mfbLoadColorMap(&cm); 64656815Sralph } 64756815Sralph 64856815Sralph for (i = 0; i < 3; i++) { 649*58793Sralph cursor_RGB[i] = 0; 65056815Sralph cursor_RGB[i + 3] = 0xff; 65156815Sralph } 65256815Sralph mfbRestoreCursorColor(); 65356815Sralph } 65456815Sralph 65556815Sralph /* 65656815Sralph * ---------------------------------------------------------------------------- 65756815Sralph * 65856815Sralph * LoadColorMap -- 65956815Sralph * 66056815Sralph * Load the color map. 66156815Sralph * 66256815Sralph * Results: 66356815Sralph * None. 66456815Sralph * 66556815Sralph * Side effects: 66656815Sralph * The color map is loaded. 66756815Sralph * 66856815Sralph * ---------------------------------------------------------------------------- 66956815Sralph */ 67056815Sralph static void 67156815Sralph mfbLoadColorMap(ptr) 67256815Sralph ColorMap *ptr; 67356815Sralph { 674*58793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 675*58793Sralph MFB_OFFSET_BT455); 67656815Sralph 67756815Sralph if (ptr->index > 15) 67856815Sralph return; 67956815Sralph 68056815Sralph BT455_SELECT_ENTRY(regs, ptr->index); 68156815Sralph regs->addr_cmap_data = ptr->Entry.red >> 12; 68256815Sralph MachEmptyWriteBuffer(); 68356815Sralph regs->addr_cmap_data = ptr->Entry.green >> 12; 68456815Sralph MachEmptyWriteBuffer(); 68556815Sralph regs->addr_cmap_data = ptr->Entry.blue >> 12; 68656815Sralph MachEmptyWriteBuffer(); 68756815Sralph } 68856815Sralph 68956815Sralph /* 69056815Sralph * Video on/off state. 69156815Sralph */ 69256815Sralph static struct vstate { 69356815Sralph u_char color0[6]; /* saved color map entry zero */ 69456815Sralph u_char off; /* TRUE if display is off */ 695*58793Sralph u_char cursor[6]; /* saved cursor color */ 69656815Sralph } vstate; 69756815Sralph 69856815Sralph /* 69956815Sralph * ---------------------------------------------------------------------------- 70056815Sralph * 70156815Sralph * bt455_video_on 70256815Sralph * 70356815Sralph * Enable the video display. 70456815Sralph * 70556815Sralph * Results: 70656815Sralph * None. 70756815Sralph * 70856815Sralph * Side effects: 70956815Sralph * The display is enabled. 71056815Sralph * 71156815Sralph * ---------------------------------------------------------------------------- 71256815Sralph */ 71356815Sralph static void 71456815Sralph bt455_video_on() 71556815Sralph { 716*58793Sralph register int i; 717*58793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 718*58793Sralph MFB_OFFSET_BT455); 71956815Sralph 72056815Sralph if (!vstate.off) 72156815Sralph return; 72256815Sralph 72356815Sralph /* restore old color map entry zero */ 72456815Sralph BT455_SELECT_ENTRY(regs, 0); 725*58793Sralph for (i = 0; i < 6; i++) { 726*58793Sralph regs->addr_cmap_data = vstate.color0[i]; 727*58793Sralph MachEmptyWriteBuffer(); 728*58793Sralph cursor_RGB[i] = vstate.cursor[i]; 729*58793Sralph } 730*58793Sralph mfbRestoreCursorColor(); 73156815Sralph vstate.off = 0; 73256815Sralph } 73356815Sralph 73456815Sralph /* 73556815Sralph * ---------------------------------------------------------------------------- 73656815Sralph * 73756815Sralph * bt455_video_off 73856815Sralph * 73956815Sralph * Disable the video display. 74056815Sralph * 74156815Sralph * Results: 74256815Sralph * None. 74356815Sralph * 74456815Sralph * Side effects: 74556815Sralph * The display is disabled. 74656815Sralph * 74756815Sralph * ---------------------------------------------------------------------------- 74856815Sralph */ 74956815Sralph static void 75056815Sralph bt455_video_off() 75156815Sralph { 752*58793Sralph register int i; 753*58793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 754*58793Sralph MFB_OFFSET_BT455); 75556815Sralph ColorMap cm; 75656815Sralph 75756815Sralph if (vstate.off) 75856815Sralph return; 75956815Sralph 76056815Sralph /* save old color map entry zero */ 76156815Sralph BT455_SELECT_ENTRY(regs, 0); 762*58793Sralph for (i = 0; i < 6; i++) { 763*58793Sralph vstate.color0[i] = regs->addr_cmap_data; 764*58793Sralph vstate.cursor[i] = cursor_RGB[i]; 765*58793Sralph cursor_RGB[i] = 0; 766*58793Sralph } 76756815Sralph 76856815Sralph /* set color map entry zero to zero */ 76956815Sralph cm.index = 0; 77056815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 77156815Sralph mfbLoadColorMap(&cm); 77256815Sralph cm.index = 1; 77356815Sralph mfbLoadColorMap(&cm); 77456815Sralph 775*58793Sralph mfbRestoreCursorColor(); 77656815Sralph vstate.off = 1; 77756815Sralph } 77856815Sralph 77956815Sralph /* 78056815Sralph * mfb keyboard and mouse input. Just punt to the generic ones in fb.c 78156815Sralph */ 78256815Sralph void 78356815Sralph mfbKbdEvent(ch) 78456815Sralph int ch; 78556815Sralph { 78656815Sralph fbKbdEvent(ch, &mfbfb); 78756815Sralph } 78856815Sralph 78956815Sralph void 79056815Sralph mfbMouseEvent(newRepPtr) 79156815Sralph MouseReport *newRepPtr; 79256815Sralph { 79356815Sralph fbMouseEvent(newRepPtr, &mfbfb); 79456815Sralph } 79556815Sralph 79656815Sralph void 79756815Sralph mfbMouseButtons(newRepPtr) 79856815Sralph MouseReport *newRepPtr; 79956815Sralph { 80056815Sralph fbMouseButtons(newRepPtr, &mfbfb); 80156815Sralph } 80256815Sralph 80356815Sralph /* 80456815Sralph * Configure the mouse and keyboard based on machine type 80556815Sralph */ 80656815Sralph static void 80756815Sralph mfbConfigMouse() 80856815Sralph { 80956815Sralph int s; 81056815Sralph 81156815Sralph s = spltty(); 81256815Sralph switch (pmax_boardtype) { 81356815Sralph #if NDC > 0 81456815Sralph case DS_3MAX: 81556815Sralph dcDivertXInput = mfbKbdEvent; 81656815Sralph dcMouseEvent = mfbMouseEvent; 81756815Sralph dcMouseButtons = mfbMouseButtons; 81856815Sralph break; 81956815Sralph #endif 82056815Sralph #if NSCC > 1 82156815Sralph case DS_3MIN: 82256815Sralph sccDivertXInput = mfbKbdEvent; 82356815Sralph sccMouseEvent = mfbMouseEvent; 82456815Sralph sccMouseButtons = mfbMouseButtons; 82556815Sralph break; 82656815Sralph #endif 82756815Sralph #if NDTOP > 0 82856815Sralph case DS_MAXINE: 82956815Sralph dtopDivertXInput = mfbKbdEvent; 83056815Sralph dtopMouseEvent = mfbMouseEvent; 83156815Sralph dtopMouseButtons = mfbMouseButtons; 83256815Sralph break; 83356815Sralph #endif 83456815Sralph default: 83556815Sralph printf("Can't configure mouse/keyboard\n"); 83656815Sralph }; 83756815Sralph splx(s); 83856815Sralph } 83956815Sralph 84056815Sralph /* 84156815Sralph * and deconfigure them 84256815Sralph */ 84356815Sralph static void 84456815Sralph mfbDeconfigMouse() 84556815Sralph { 84656815Sralph int s; 84756815Sralph 84856815Sralph s = spltty(); 84956815Sralph switch (pmax_boardtype) { 85056815Sralph #if NDC > 0 85156815Sralph case DS_3MAX: 85256815Sralph dcDivertXInput = (void (*)())0; 85356815Sralph dcMouseEvent = (void (*)())0; 85456815Sralph dcMouseButtons = (void (*)())0; 85556815Sralph break; 85656815Sralph #endif 85756815Sralph #if NSCC > 1 85856815Sralph case DS_3MIN: 85956815Sralph sccDivertXInput = (void (*)())0; 86056815Sralph sccMouseEvent = (void (*)())0; 86156815Sralph sccMouseButtons = (void (*)())0; 86256815Sralph break; 86356815Sralph #endif 86456815Sralph #if NDTOP > 0 86556815Sralph case DS_MAXINE: 86656815Sralph dtopDivertXInput = (void (*)())0; 86756815Sralph dtopMouseEvent = (void (*)())0; 86856815Sralph dtopMouseButtons = (void (*)())0; 86956815Sralph break; 87056815Sralph #endif 87156815Sralph default: 87256815Sralph printf("Can't deconfigure mouse/keyboard\n"); 87356815Sralph }; 87456815Sralph } 87556815Sralph 87656815Sralph /* 87756815Sralph * Generic register access 87856815Sralph */ 87956815Sralph static void 88056815Sralph bt431_select_reg(regs, regno) 88156815Sralph bt431_regmap_t *regs; 88256815Sralph { 88356815Sralph regs->addr_lo = SET_VALUE(regno & 0xff); 88456815Sralph regs->addr_hi = SET_VALUE((regno >> 8) & 0xff); 88556815Sralph MachEmptyWriteBuffer(); 88656815Sralph } 88756815Sralph 88856815Sralph static void 88956815Sralph bt431_write_reg(regs, regno, val) 89056815Sralph bt431_regmap_t *regs; 89156815Sralph { 89256815Sralph bt431_select_reg(regs, regno); 89356815Sralph regs->addr_reg = SET_VALUE(val); 89456815Sralph MachEmptyWriteBuffer(); 89556815Sralph } 89656815Sralph 89756815Sralph static u_char 89856815Sralph bt431_read_reg(regs, regno) 89956815Sralph bt431_regmap_t *regs; 90056815Sralph { 90156815Sralph bt431_select_reg(regs, regno); 90256815Sralph return (GET_VALUE(regs->addr_reg)); 90356815Sralph } 90456815Sralph 90556815Sralph static void 90656815Sralph bt431_init(regs) 90756815Sralph bt431_regmap_t *regs; 90856815Sralph { 90956815Sralph register int i; 91056815Sralph 91156815Sralph /* use 4:1 input mux */ 91256815Sralph bt431_write_reg(regs, BT431_REG_CMD, 91356815Sralph BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS| 91456815Sralph BT431_CMD_4_1_MUX|BT431_CMD_THICK_1); 91556815Sralph 91656815Sralph /* home cursor */ 91756815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91856815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91956815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92056815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92156815Sralph 92256815Sralph /* no crosshair window */ 92356815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92456815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92556815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92656815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92756815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92856815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92956815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 93056815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 93156815Sralph } 93256815Sralph #endif /* NMFB */ 933