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*57234Sralph * @(#)mfb.c 7.2 (Berkeley) 12/20/92 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; 16756815Sralph mfbInitColorMap(); 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; 19256815Sralph mfbInitColorMap(); 19356815Sralph mfbDeconfigMouse(); 19456815Sralph mfbScreenInit(); 19556815Sralph vmUserUnmap(); 19656815Sralph bzero((caddr_t)fp->fr_addr, 256 * 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 */ 22956815Sralph addr = vmUserMap(256 * 1024, 23056815Sralph (unsigned)(fp->fr_addr + MFB_OFFSET_VRAM)); 23156815Sralph if (addr == (caddr_t)0) 23256815Sralph goto mapError; 23356815Sralph fp->fbu->scrInfo.bitmap = (char *)addr; 23456815Sralph break; 23556815Sralph 23656815Sralph mapError: 23756815Sralph vmUserUnmap(); 23856815Sralph printf("Cannot map shared data structures\n"); 23956815Sralph return (EIO); 24056815Sralph } 24156815Sralph 24256815Sralph case QIOCPMSTATE: 24356815Sralph /* 24456815Sralph * Set mouse state. 24556815Sralph */ 24656815Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 24756815Sralph mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 24856815Sralph break; 24956815Sralph 25056815Sralph case QIOCINIT: 25156815Sralph /* 25256815Sralph * Initialize the screen. 25356815Sralph */ 25456815Sralph mfbScreenInit(); 25556815Sralph break; 25656815Sralph 25756815Sralph case QIOCKPCMD: 25856815Sralph { 25956815Sralph pmKpCmd *kpCmdPtr; 26056815Sralph unsigned char *cp; 26156815Sralph 26256815Sralph kpCmdPtr = (pmKpCmd *)data; 26356815Sralph if (kpCmdPtr->nbytes == 0) 26456815Sralph kpCmdPtr->cmd |= 0x80; 26556815Sralph if (!fp->GraphicsOpen) 26656815Sralph kpCmdPtr->cmd |= 1; 26756815Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 26856815Sralph cp = &kpCmdPtr->par[0]; 26956815Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 27056815Sralph if (kpCmdPtr->nbytes == 1) 27156815Sralph *cp |= 0x80; 27256815Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 27356815Sralph } 27456815Sralph } 27556815Sralph break; 27656815Sralph 27756815Sralph case QIOCADDR: 27856815Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 27956815Sralph break; 28056815Sralph 28156815Sralph case QIOWCURSOR: 28256815Sralph mfbLoadCursor((unsigned short *)data); 28356815Sralph break; 28456815Sralph 28556815Sralph case QIOWCURSORCOLOR: 28656815Sralph mfbCursorColor((unsigned int *)data); 28756815Sralph break; 28856815Sralph 28956815Sralph case QIOSETCMAP: 29056815Sralph mfbLoadColorMap((ColorMap *)data); 29156815Sralph break; 29256815Sralph 29356815Sralph case QIOKERNLOOP: 29456815Sralph mfbConfigMouse(); 29556815Sralph break; 29656815Sralph 29756815Sralph case QIOKERNUNLOOP: 29856815Sralph mfbDeconfigMouse(); 29956815Sralph break; 30056815Sralph 30156815Sralph case QIOVIDEOON: 30256815Sralph mfbRestoreCursorColor(); 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 35156815Sralph regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431); 35256815Sralph /* 35356815Sralph * Fill in the cursor sprite using the A and B planes, as provided 35456815Sralph * for the pmax. 35556815Sralph * XXX This will have to change when the X server knows that this 35656815Sralph * is not a pmax display. 35756815Sralph */ 35856815Sralph pos = 0; 35956815Sralph bt431_select_reg(regs, BT431_REG_CRAM_BASE); 36056815Sralph for (k = 0; k < 16; k++) { 36156815Sralph ap = *cursor; 36256815Sralph bp = *(cursor + 16); 36356815Sralph j = 0; 36456815Sralph while (j < 2) { 36556815Sralph out = 0; 36656815Sralph for (i = 0; i < 8; i++) { 367*57234Sralph #ifdef CURSOR_EL 36856815Sralph out = (out << 1) | ((ap & 0x1) << 8) | 36956815Sralph (bp & 0x1); 370*57234Sralph #else 371*57234Sralph out = ((out >> 1) & 0x7f7f) | 372*57234Sralph ((ap & 0x1) << 15) | 373*57234Sralph ((bp & 0x1) << 7); 374*57234Sralph #endif 37556815Sralph ap >>= 1; 37656815Sralph bp >>= 1; 37756815Sralph } 37856815Sralph BT431_WRITE_CMAP_AUTOI(regs, out); 37956815Sralph pos++; 38056815Sralph j++; 38156815Sralph } 38256815Sralph while (j < 8) { 38356815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 38456815Sralph pos++; 38556815Sralph j++; 38656815Sralph } 38756815Sralph cursor++; 38856815Sralph } 38956815Sralph while (pos < 512) { 39056815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 39156815Sralph pos++; 39256815Sralph } 39356815Sralph } 39456815Sralph 39556815Sralph /* 39656815Sralph * Initialization 39756815Sralph */ 39856815Sralph int 39956815Sralph mfbinit(cp) 40056815Sralph char *cp; 40156815Sralph { 40256815Sralph register struct pmax_fb *fp = &mfbfb; 40356815Sralph 40456815Sralph /* check for no frame buffer */ 40556815Sralph if (badaddr(cp, 4)) 40656815Sralph return (0); 40756815Sralph 40856815Sralph fp->isMono = 1; 40956815Sralph fp->fr_addr = (char *)cp; 410*57234Sralph /* 411*57234Sralph * Must be in Uncached space or the Xserver sees a stale version of 412*57234Sralph * the event queue and acts totally wacko. I don't understand this, 413*57234Sralph * since the R3000 uses a physical address cache? 414*57234Sralph */ 415*57234Sralph fp->fbu = (struct fbuaccess *) 416*57234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu)); 41756815Sralph fp->posCursor = mfbPosCursor; 418*57234Sralph if (tb_kbdmouseconfig(fp)) 41956815Sralph return (0); 42056815Sralph 42156815Sralph /* 42256815Sralph * Initialize the screen. 42356815Sralph */ 42456815Sralph bt431_init(fp->fr_addr + MFB_OFFSET_BT431); 42556815Sralph 42656815Sralph /* 42756815Sralph * Initialize screen info. 42856815Sralph */ 42956815Sralph fp->fbu->scrInfo.max_row = 67; 43056815Sralph fp->fbu->scrInfo.max_col = 80; 43156815Sralph fp->fbu->scrInfo.max_x = 1280; 43256815Sralph fp->fbu->scrInfo.max_y = 1024; 43356815Sralph fp->fbu->scrInfo.max_cur_x = 1279; 43456815Sralph fp->fbu->scrInfo.max_cur_y = 1023; 43556815Sralph fp->fbu->scrInfo.version = 11; 43656815Sralph fp->fbu->scrInfo.mthreshold = 4; 43756815Sralph fp->fbu->scrInfo.mscale = 2; 43856815Sralph fp->fbu->scrInfo.min_cur_x = 0; 43956815Sralph fp->fbu->scrInfo.min_cur_y = 0; 44056815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 44156815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 44256815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 44356815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 44456815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 44556815Sralph 44656815Sralph /* 44756815Sralph * Initialize the color map, the screen, and the mouse. 44856815Sralph */ 44956815Sralph mfbInitColorMap(); 45056815Sralph mfbScreenInit(); 45156815Sralph fbScroll(fp); 45256815Sralph 45356815Sralph fp->initialized = 1; 45456815Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 45556815Sralph cn_tab.cn_fb = fp; 45656815Sralph return (1); 45756815Sralph } 45856815Sralph 45956815Sralph /* 46056815Sralph * ---------------------------------------------------------------------------- 46156815Sralph * 46256815Sralph * mfbScreenInit -- 46356815Sralph * 46456815Sralph * Initialize the screen. 46556815Sralph * 46656815Sralph * Results: 46756815Sralph * None. 46856815Sralph * 46956815Sralph * Side effects: 47056815Sralph * The screen is initialized. 47156815Sralph * 47256815Sralph * ---------------------------------------------------------------------------- 47356815Sralph */ 47456815Sralph static void 47556815Sralph mfbScreenInit() 47656815Sralph { 47756815Sralph register struct pmax_fb *fp = &mfbfb; 47856815Sralph 47956815Sralph /* 48056815Sralph * Home the cursor. 48156815Sralph * We want an LSI terminal emulation. We want the graphics 48256815Sralph * terminal to scroll from the bottom. So start at the bottom. 48356815Sralph */ 48456815Sralph fp->row = 66; 48556815Sralph fp->col = 0; 48656815Sralph 48756815Sralph /* 48856815Sralph * Load the cursor with the default values 48956815Sralph * 49056815Sralph */ 49156815Sralph mfbLoadCursor(defCursor); 49256815Sralph } 49356815Sralph 49456815Sralph /* 49556815Sralph * ---------------------------------------------------------------------------- 49656815Sralph * 49756815Sralph * RestoreCursorColor -- 49856815Sralph * 49956815Sralph * Routine to restore the color of the cursor. 50056815Sralph * 50156815Sralph * Results: 50256815Sralph * None. 50356815Sralph * 50456815Sralph * Side effects: 50556815Sralph * None. 50656815Sralph * 50756815Sralph * ---------------------------------------------------------------------------- 50856815Sralph */ 50956815Sralph static void 51056815Sralph mfbRestoreCursorColor() 51156815Sralph { 51256815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 51356815Sralph ColorMap cm; 51456815Sralph register int i; 51556815Sralph 51656815Sralph cm.index = 8; 51756815Sralph cm.Entry.red = cursor_RGB[0] << 8; 51856815Sralph cm.Entry.green = cursor_RGB[1] << 8; 51956815Sralph cm.Entry.blue = cursor_RGB[2] << 8; 52056815Sralph mfbLoadColorMap(&cm); 52156815Sralph cm.index = 9; 52256815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 52356815Sralph mfbLoadColorMap(&cm); 52456815Sralph 52556815Sralph regs->addr_ovly = cursor_RGB[3] >> 4; 52656815Sralph MachEmptyWriteBuffer(); 52756815Sralph regs->addr_ovly = cursor_RGB[4] >> 4; 52856815Sralph MachEmptyWriteBuffer(); 52956815Sralph regs->addr_ovly = cursor_RGB[5] >> 4; 53056815Sralph MachEmptyWriteBuffer(); 53156815Sralph } 53256815Sralph 53356815Sralph /* 53456815Sralph * ---------------------------------------------------------------------------- 53556815Sralph * 53656815Sralph * CursorColor -- 53756815Sralph * 53856815Sralph * Set the color of the cursor. 53956815Sralph * 54056815Sralph * Results: 54156815Sralph * None. 54256815Sralph * 54356815Sralph * Side effects: 54456815Sralph * None. 54556815Sralph * 54656815Sralph * ---------------------------------------------------------------------------- 54756815Sralph */ 54856815Sralph static void 54956815Sralph mfbCursorColor(color) 55056815Sralph unsigned int color[]; 55156815Sralph { 55256815Sralph register int i, j; 55356815Sralph 55456815Sralph for (i = 0; i < 6; i++) 55556815Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 55656815Sralph 55756815Sralph mfbRestoreCursorColor(); 55856815Sralph } 55956815Sralph 56056815Sralph /* 56156815Sralph *---------------------------------------------------------------------- 56256815Sralph * 56356815Sralph * PosCursor -- 56456815Sralph * 56556815Sralph * Postion the cursor. 56656815Sralph * 56756815Sralph * Results: 56856815Sralph * None. 56956815Sralph * 57056815Sralph * Side effects: 57156815Sralph * None. 57256815Sralph * 57356815Sralph *---------------------------------------------------------------------- 57456815Sralph */ 57556815Sralph void 57656815Sralph mfbPosCursor(x, y) 57756815Sralph register int x, y; 57856815Sralph { 57956815Sralph bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431); 58056815Sralph register struct pmax_fb *fp = &mfbfb; 58156815Sralph 58256815Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 58356815Sralph y = fp->fbu->scrInfo.max_cur_y; 58456815Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 58556815Sralph x = fp->fbu->scrInfo.max_cur_x; 58656815Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 58756815Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 58856815Sralph 58956815Sralph #define lo(v) ((v)&0xff) 59056815Sralph #define hi(v) (((v)&0xf00)>>8) 59156815Sralph 59256815Sralph /* 59356815Sralph * Cx = x + D + H - P 59456815Sralph * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 59556815Sralph * D = pixel skew between outdata and external data 59656815Sralph * H = pixels between HSYNCH falling and active video 59756815Sralph * 59856815Sralph * Cy = y + V - 32 59956815Sralph * V = scanlines between HSYNCH falling, two or more 60056815Sralph * clocks after VSYNCH falling, and active video 60156815Sralph */ 60256815Sralph 60356815Sralph bt431_write_reg(regs, lo(x + 360)); 60456815Sralph BT431_WRITE_REG_AUTOI(regs, hi(x + 360)); 60556815Sralph BT431_WRITE_REG_AUTOI(regs, lo(y + 36)); 60656815Sralph BT431_WRITE_REG_AUTOI(regs, hi(y + 36)); 60756815Sralph } 60856815Sralph 60956815Sralph /* 61056815Sralph * ---------------------------------------------------------------------------- 61156815Sralph * 61256815Sralph * InitColorMap -- 61356815Sralph * 61456815Sralph * Initialize the color map. 61556815Sralph * 61656815Sralph * Results: 61756815Sralph * None. 61856815Sralph * 61956815Sralph * Side effects: 62056815Sralph * The colormap is initialized appropriately. 62156815Sralph * 62256815Sralph * ---------------------------------------------------------------------------- 62356815Sralph */ 62456815Sralph static void 62556815Sralph mfbInitColorMap() 62656815Sralph { 62756815Sralph ColorMap cm; 62856815Sralph register int i; 62956815Sralph 63056815Sralph cm.index = 0; 63156815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 63256815Sralph mfbLoadColorMap(&cm); 63356815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 63456815Sralph for (i = 1; i < 16; i++) { 63556815Sralph cm.index = i; 63656815Sralph mfbLoadColorMap(&cm); 63756815Sralph } 63856815Sralph 63956815Sralph for (i = 0; i < 3; i++) { 64056815Sralph cursor_RGB[i] = 0x00; 64156815Sralph cursor_RGB[i + 3] = 0xff; 64256815Sralph } 64356815Sralph mfbRestoreCursorColor(); 64456815Sralph } 64556815Sralph 64656815Sralph /* 64756815Sralph * ---------------------------------------------------------------------------- 64856815Sralph * 64956815Sralph * LoadColorMap -- 65056815Sralph * 65156815Sralph * Load the color map. 65256815Sralph * 65356815Sralph * Results: 65456815Sralph * None. 65556815Sralph * 65656815Sralph * Side effects: 65756815Sralph * The color map is loaded. 65856815Sralph * 65956815Sralph * ---------------------------------------------------------------------------- 66056815Sralph */ 66156815Sralph static void 66256815Sralph mfbLoadColorMap(ptr) 66356815Sralph ColorMap *ptr; 66456815Sralph { 66556815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 66656815Sralph 66756815Sralph if (ptr->index > 15) 66856815Sralph return; 66956815Sralph 67056815Sralph BT455_SELECT_ENTRY(regs, ptr->index); 67156815Sralph regs->addr_cmap_data = ptr->Entry.red >> 12; 67256815Sralph MachEmptyWriteBuffer(); 67356815Sralph regs->addr_cmap_data = ptr->Entry.green >> 12; 67456815Sralph MachEmptyWriteBuffer(); 67556815Sralph regs->addr_cmap_data = ptr->Entry.blue >> 12; 67656815Sralph MachEmptyWriteBuffer(); 67756815Sralph } 67856815Sralph 67956815Sralph /* 68056815Sralph * Video on/off state. 68156815Sralph */ 68256815Sralph static struct vstate { 68356815Sralph u_char color0[6]; /* saved color map entry zero */ 68456815Sralph u_char off; /* TRUE if display is off */ 68556815Sralph } vstate; 68656815Sralph 68756815Sralph /* 68856815Sralph * ---------------------------------------------------------------------------- 68956815Sralph * 69056815Sralph * bt455_video_on 69156815Sralph * 69256815Sralph * Enable the video display. 69356815Sralph * 69456815Sralph * Results: 69556815Sralph * None. 69656815Sralph * 69756815Sralph * Side effects: 69856815Sralph * The display is enabled. 69956815Sralph * 70056815Sralph * ---------------------------------------------------------------------------- 70156815Sralph */ 70256815Sralph static void 70356815Sralph bt455_video_on() 70456815Sralph { 70556815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 70656815Sralph 70756815Sralph if (!vstate.off) 70856815Sralph return; 70956815Sralph 71056815Sralph /* restore old color map entry zero */ 71156815Sralph BT455_SELECT_ENTRY(regs, 0); 71256815Sralph regs->addr_cmap_data = vstate.color0[0]; 71356815Sralph MachEmptyWriteBuffer(); 71456815Sralph regs->addr_cmap_data = vstate.color0[1]; 71556815Sralph MachEmptyWriteBuffer(); 71656815Sralph regs->addr_cmap_data = vstate.color0[2]; 71756815Sralph MachEmptyWriteBuffer(); 71856815Sralph regs->addr_cmap_data = vstate.color0[3]; 71956815Sralph MachEmptyWriteBuffer(); 72056815Sralph regs->addr_cmap_data = vstate.color0[4]; 72156815Sralph MachEmptyWriteBuffer(); 72256815Sralph regs->addr_cmap_data = vstate.color0[5]; 72356815Sralph MachEmptyWriteBuffer(); 72456815Sralph 72556815Sralph vstate.off = 0; 72656815Sralph } 72756815Sralph 72856815Sralph /* 72956815Sralph * ---------------------------------------------------------------------------- 73056815Sralph * 73156815Sralph * bt455_video_off 73256815Sralph * 73356815Sralph * Disable the video display. 73456815Sralph * 73556815Sralph * Results: 73656815Sralph * None. 73756815Sralph * 73856815Sralph * Side effects: 73956815Sralph * The display is disabled. 74056815Sralph * 74156815Sralph * ---------------------------------------------------------------------------- 74256815Sralph */ 74356815Sralph static void 74456815Sralph bt455_video_off() 74556815Sralph { 74656815Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455); 74756815Sralph ColorMap cm; 74856815Sralph 74956815Sralph if (vstate.off) 75056815Sralph return; 75156815Sralph 75256815Sralph /* save old color map entry zero */ 75356815Sralph BT455_SELECT_ENTRY(regs, 0); 75456815Sralph vstate.color0[0] = regs->addr_cmap_data; 75556815Sralph vstate.color0[1] = regs->addr_cmap_data; 75656815Sralph vstate.color0[2] = regs->addr_cmap_data; 75756815Sralph vstate.color0[3] = regs->addr_cmap_data; 75856815Sralph vstate.color0[4] = regs->addr_cmap_data; 75956815Sralph vstate.color0[5] = regs->addr_cmap_data; 76056815Sralph 76156815Sralph /* set color map entry zero to zero */ 76256815Sralph cm.index = 0; 76356815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 76456815Sralph mfbLoadColorMap(&cm); 76556815Sralph cm.index = 1; 76656815Sralph mfbLoadColorMap(&cm); 76756815Sralph 76856815Sralph vstate.off = 1; 76956815Sralph } 77056815Sralph 77156815Sralph /* 77256815Sralph * mfb keyboard and mouse input. Just punt to the generic ones in fb.c 77356815Sralph */ 77456815Sralph void 77556815Sralph mfbKbdEvent(ch) 77656815Sralph int ch; 77756815Sralph { 77856815Sralph fbKbdEvent(ch, &mfbfb); 77956815Sralph } 78056815Sralph 78156815Sralph void 78256815Sralph mfbMouseEvent(newRepPtr) 78356815Sralph MouseReport *newRepPtr; 78456815Sralph { 78556815Sralph fbMouseEvent(newRepPtr, &mfbfb); 78656815Sralph } 78756815Sralph 78856815Sralph void 78956815Sralph mfbMouseButtons(newRepPtr) 79056815Sralph MouseReport *newRepPtr; 79156815Sralph { 79256815Sralph fbMouseButtons(newRepPtr, &mfbfb); 79356815Sralph } 79456815Sralph 79556815Sralph /* 79656815Sralph * Configure the mouse and keyboard based on machine type 79756815Sralph */ 79856815Sralph static void 79956815Sralph mfbConfigMouse() 80056815Sralph { 80156815Sralph int s; 80256815Sralph 80356815Sralph s = spltty(); 80456815Sralph switch (pmax_boardtype) { 80556815Sralph #if NDC > 0 80656815Sralph case DS_3MAX: 80756815Sralph dcDivertXInput = mfbKbdEvent; 80856815Sralph dcMouseEvent = mfbMouseEvent; 80956815Sralph dcMouseButtons = mfbMouseButtons; 81056815Sralph break; 81156815Sralph #endif 81256815Sralph #if NSCC > 1 81356815Sralph case DS_3MIN: 81456815Sralph sccDivertXInput = mfbKbdEvent; 81556815Sralph sccMouseEvent = mfbMouseEvent; 81656815Sralph sccMouseButtons = mfbMouseButtons; 81756815Sralph break; 81856815Sralph #endif 81956815Sralph #if NDTOP > 0 82056815Sralph case DS_MAXINE: 82156815Sralph dtopDivertXInput = mfbKbdEvent; 82256815Sralph dtopMouseEvent = mfbMouseEvent; 82356815Sralph dtopMouseButtons = mfbMouseButtons; 82456815Sralph break; 82556815Sralph #endif 82656815Sralph default: 82756815Sralph printf("Can't configure mouse/keyboard\n"); 82856815Sralph }; 82956815Sralph splx(s); 83056815Sralph } 83156815Sralph 83256815Sralph /* 83356815Sralph * and deconfigure them 83456815Sralph */ 83556815Sralph static void 83656815Sralph mfbDeconfigMouse() 83756815Sralph { 83856815Sralph int s; 83956815Sralph 84056815Sralph s = spltty(); 84156815Sralph switch (pmax_boardtype) { 84256815Sralph #if NDC > 0 84356815Sralph case DS_3MAX: 84456815Sralph dcDivertXInput = (void (*)())0; 84556815Sralph dcMouseEvent = (void (*)())0; 84656815Sralph dcMouseButtons = (void (*)())0; 84756815Sralph break; 84856815Sralph #endif 84956815Sralph #if NSCC > 1 85056815Sralph case DS_3MIN: 85156815Sralph sccDivertXInput = (void (*)())0; 85256815Sralph sccMouseEvent = (void (*)())0; 85356815Sralph sccMouseButtons = (void (*)())0; 85456815Sralph break; 85556815Sralph #endif 85656815Sralph #if NDTOP > 0 85756815Sralph case DS_MAXINE: 85856815Sralph dtopDivertXInput = (void (*)())0; 85956815Sralph dtopMouseEvent = (void (*)())0; 86056815Sralph dtopMouseButtons = (void (*)())0; 86156815Sralph break; 86256815Sralph #endif 86356815Sralph default: 86456815Sralph printf("Can't deconfigure mouse/keyboard\n"); 86556815Sralph }; 86656815Sralph } 86756815Sralph 86856815Sralph /* 86956815Sralph * Generic register access 87056815Sralph */ 87156815Sralph static void 87256815Sralph bt431_select_reg(regs, regno) 87356815Sralph bt431_regmap_t *regs; 87456815Sralph { 87556815Sralph regs->addr_lo = SET_VALUE(regno & 0xff); 87656815Sralph regs->addr_hi = SET_VALUE((regno >> 8) & 0xff); 87756815Sralph MachEmptyWriteBuffer(); 87856815Sralph } 87956815Sralph 88056815Sralph static void 88156815Sralph bt431_write_reg(regs, regno, val) 88256815Sralph bt431_regmap_t *regs; 88356815Sralph { 88456815Sralph bt431_select_reg(regs, regno); 88556815Sralph regs->addr_reg = SET_VALUE(val); 88656815Sralph MachEmptyWriteBuffer(); 88756815Sralph } 88856815Sralph 88956815Sralph static u_char 89056815Sralph bt431_read_reg(regs, regno) 89156815Sralph bt431_regmap_t *regs; 89256815Sralph { 89356815Sralph bt431_select_reg(regs, regno); 89456815Sralph return (GET_VALUE(regs->addr_reg)); 89556815Sralph } 89656815Sralph 89756815Sralph static void 89856815Sralph bt431_init(regs) 89956815Sralph bt431_regmap_t *regs; 90056815Sralph { 90156815Sralph register int i; 90256815Sralph 90356815Sralph /* use 4:1 input mux */ 90456815Sralph bt431_write_reg(regs, BT431_REG_CMD, 90556815Sralph BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS| 90656815Sralph BT431_CMD_4_1_MUX|BT431_CMD_THICK_1); 90756815Sralph 90856815Sralph /* home cursor */ 90956815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91056815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91156815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91256815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91356815Sralph 91456815Sralph /* no crosshair window */ 91556815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91656815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 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 BT431_WRITE_REG_AUTOI(regs, 0x00); 92256815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 92356815Sralph } 92456815Sralph #endif /* NMFB */ 925