156815Sralph /*- 2*63206Sbostic * Copyright (c) 1992, 1993 3*63206Sbostic * The Regents of the University of California. 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*63206Sbostic * @(#)mfb.c 8.1 (Berkeley) 06/10/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 static void mfbScreenInit(); 9256815Sralph static void mfbLoadCursor(); 9356815Sralph static void mfbRestoreCursorColor(); 9456815Sralph static void mfbCursorColor(); 9556815Sralph void mfbPosCursor(); 9656815Sralph static void mfbInitColorMap(); 9756815Sralph static void mfbLoadColorMap(); 9856815Sralph static void mfbConfigMouse(), mfbDeconfigMouse(); 9956815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg(); 10056815Sralph static void bt431_write_reg(), bt431_init(); 10156815Sralph static u_char bt431_read_reg(); 10256815Sralph 10356815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons(); 10456815Sralph #if NDC > 0 10556815Sralph extern void (*dcDivertXInput)(); 10656815Sralph extern void (*dcMouseEvent)(); 10756815Sralph extern void (*dcMouseButtons)(); 10856815Sralph #endif 10956815Sralph #if NSCC > 0 11056815Sralph extern void (*sccDivertXInput)(); 11156815Sralph extern void (*sccMouseEvent)(); 11256815Sralph extern void (*sccMouseButtons)(); 11356815Sralph #endif 11456815Sralph #if NDTOP > 0 11556815Sralph extern void (*dtopDivertXInput)(); 11656815Sralph extern void (*dtopMouseEvent)(); 11756815Sralph extern void (*dtopMouseButtons)(); 11856815Sralph #endif 11956815Sralph extern int pmax_boardtype; 12056815Sralph extern u_short defCursor[32]; 12156815Sralph extern struct consdev cn_tab; 12256815Sralph 12356815Sralph int mfbprobe(); 12456815Sralph struct driver mfbdriver = { 12556815Sralph "mfb", mfbprobe, 0, 0, 12656815Sralph }; 12756815Sralph 12856815Sralph #define MFB_OFFSET_VRAM 0x200000 /* from module's base */ 12956815Sralph #define MFB_OFFSET_BT431 0x180000 /* Bt431 registers */ 13056815Sralph #define MFB_OFFSET_BT455 0x100000 /* Bt455 registers */ 13156815Sralph #define MFB_OFFSET_IREQ 0x080000 /* Interrupt req. control */ 13256815Sralph #define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */ 13359069Sralph #define MFB_FB_SIZE 0x200000 /* frame buffer size */ 13456815Sralph 13556815Sralph /* 13656815Sralph * Test to see if device is present. 13756815Sralph * Return true if found and initialized ok. 13856815Sralph */ 13956815Sralph /*ARGSUSED*/ 14056815Sralph mfbprobe(cp) 14156815Sralph register struct pmax_ctlr *cp; 14256815Sralph { 14356815Sralph register struct pmax_fb *fp = &mfbfb; 14456815Sralph 14556815Sralph if (!fp->initialized && !mfbinit(cp->pmax_addr)) 14656815Sralph return (0); 14756815Sralph printf("mfb0 (mono display)\n"); 14856815Sralph return (1); 14956815Sralph } 15056815Sralph 15156815Sralph /*ARGSUSED*/ 15256815Sralph mfbopen(dev, flag) 15356815Sralph dev_t dev; 15456815Sralph int flag; 15556815Sralph { 15656815Sralph register struct pmax_fb *fp = &mfbfb; 15756815Sralph int s; 15856815Sralph 15956815Sralph if (!fp->initialized) 16056815Sralph return (ENXIO); 16156815Sralph if (fp->GraphicsOpen) 16256815Sralph return (EBUSY); 16356815Sralph 16456815Sralph fp->GraphicsOpen = 1; 16558793Sralph mfbInitColorMap(1); 16656815Sralph /* 16756815Sralph * Set up event queue for later 16856815Sralph */ 16956815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 17056815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 17156815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 17256815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 17356815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 17456815Sralph mfbConfigMouse(); 17556815Sralph return (0); 17656815Sralph } 17756815Sralph 17856815Sralph /*ARGSUSED*/ 17956815Sralph mfbclose(dev, flag) 18056815Sralph dev_t dev; 18156815Sralph int flag; 18256815Sralph { 18356815Sralph register struct pmax_fb *fp = &mfbfb; 18456815Sralph int s; 18556815Sralph 18656815Sralph if (!fp->GraphicsOpen) 18756815Sralph return (EBADF); 18856815Sralph 18956815Sralph fp->GraphicsOpen = 0; 19058793Sralph mfbInitColorMap(0); 19156815Sralph mfbDeconfigMouse(); 19256815Sralph mfbScreenInit(); 19358793Sralph bzero((caddr_t)fp->fr_addr, 2048 * 1024); 19456815Sralph mfbPosCursor(fp->col * 8, fp->row * 15); 19556815Sralph return (0); 19656815Sralph } 19756815Sralph 19856815Sralph /*ARGSUSED*/ 19958974Sralph mfbioctl(dev, cmd, data, flag, p) 20056815Sralph dev_t dev; 20156815Sralph caddr_t data; 20258974Sralph struct proc *p; 20356815Sralph { 20456815Sralph register struct pmax_fb *fp = &mfbfb; 20556815Sralph int s; 20656815Sralph 20756815Sralph switch (cmd) { 20856815Sralph case QIOCGINFO: 20958974Sralph return (fbmmap(fp, dev, data, p)); 21056815Sralph 21156815Sralph case QIOCPMSTATE: 21256815Sralph /* 21356815Sralph * Set mouse state. 21456815Sralph */ 21556815Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 21656815Sralph mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 21756815Sralph break; 21856815Sralph 21956815Sralph case QIOCINIT: 22056815Sralph /* 22156815Sralph * Initialize the screen. 22256815Sralph */ 22356815Sralph mfbScreenInit(); 22456815Sralph break; 22556815Sralph 22656815Sralph case QIOCKPCMD: 22756815Sralph { 22856815Sralph pmKpCmd *kpCmdPtr; 22956815Sralph unsigned char *cp; 23056815Sralph 23156815Sralph kpCmdPtr = (pmKpCmd *)data; 23256815Sralph if (kpCmdPtr->nbytes == 0) 23356815Sralph kpCmdPtr->cmd |= 0x80; 23456815Sralph if (!fp->GraphicsOpen) 23556815Sralph kpCmdPtr->cmd |= 1; 23656815Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 23756815Sralph cp = &kpCmdPtr->par[0]; 23856815Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 23956815Sralph if (kpCmdPtr->nbytes == 1) 24056815Sralph *cp |= 0x80; 24156815Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 24256815Sralph } 24358974Sralph break; 24456815Sralph } 24556815Sralph 24656815Sralph case QIOCADDR: 24756815Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 24856815Sralph break; 24956815Sralph 25056815Sralph case QIOWCURSOR: 25156815Sralph mfbLoadCursor((unsigned short *)data); 25256815Sralph break; 25356815Sralph 25456815Sralph case QIOWCURSORCOLOR: 25556815Sralph mfbCursorColor((unsigned int *)data); 25656815Sralph break; 25756815Sralph 25856815Sralph case QIOSETCMAP: 25958793Sralph #ifdef notdef 26056815Sralph mfbLoadColorMap((ColorMap *)data); 26158793Sralph #endif 26256815Sralph break; 26356815Sralph 26456815Sralph case QIOKERNLOOP: 26556815Sralph mfbConfigMouse(); 26656815Sralph break; 26756815Sralph 26856815Sralph case QIOKERNUNLOOP: 26956815Sralph mfbDeconfigMouse(); 27056815Sralph break; 27156815Sralph 27256815Sralph case QIOVIDEOON: 27356815Sralph bt455_video_on(); 27456815Sralph break; 27556815Sralph 27656815Sralph case QIOVIDEOOFF: 27756815Sralph bt455_video_off(); 27856815Sralph break; 27956815Sralph 28056815Sralph default: 28156815Sralph printf("mfb0: Unknown ioctl command %x\n", cmd); 28256815Sralph return (EINVAL); 28356815Sralph } 28456815Sralph return (0); 28556815Sralph } 28656815Sralph 28758974Sralph /* 28858974Sralph * Return the physical page number that corresponds to byte offset 'off'. 28958974Sralph */ 29058974Sralph /*ARGSUSED*/ 29158974Sralph mfbmap(dev, off, prot) 29258974Sralph dev_t dev; 29358974Sralph { 29458974Sralph int len; 29558974Sralph 29658974Sralph len = pmax_round_page(((vm_offset_t)&mfbu & PGOFSET) + sizeof(mfbu)); 29758974Sralph if (off < len) 29858974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&mfbu) + off); 29958974Sralph off -= len; 30058974Sralph if (off >= mfbfb.fr_size) 30158974Sralph return (-1); 30258974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(mfbfb.fr_addr) + off); 30358974Sralph } 30458974Sralph 30556815Sralph mfbselect(dev, flag, p) 30656815Sralph dev_t dev; 30756815Sralph int flag; 30856815Sralph struct proc *p; 30956815Sralph { 31056815Sralph struct pmax_fb *fp = &mfbfb; 31156815Sralph 31256815Sralph switch (flag) { 31356815Sralph case FREAD: 31456815Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 31556815Sralph return (1); 31656815Sralph selrecord(p, &fp->selp); 31756815Sralph break; 31856815Sralph } 31956815Sralph 32056815Sralph return (0); 32156815Sralph } 32256815Sralph 32356815Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 32456815Sralph 32556815Sralph /* 32656815Sralph * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit 32756815Sralph * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding 32856815Sralph * registers for these two chips live in adjacent bytes of the shorts that 32956815Sralph * are defined in bt431_regmap_t. 33056815Sralph */ 33156815Sralph static void 33256815Sralph mfbLoadCursor(cursor) 33356815Sralph u_short *cursor; 33456815Sralph { 33556815Sralph register int i, j, k, pos; 33656815Sralph register u_short ap, bp, out; 33756815Sralph register bt431_regmap_t *regs; 33856815Sralph 33958793Sralph regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr + 34058793Sralph MFB_OFFSET_BT431); 34156815Sralph /* 34256815Sralph * Fill in the cursor sprite using the A and B planes, as provided 34356815Sralph * for the pmax. 34456815Sralph * XXX This will have to change when the X server knows that this 34558793Sralph * is not a pmax display. (ie. Not the Xcfbpmax server.) 34656815Sralph */ 34756815Sralph pos = 0; 34856815Sralph bt431_select_reg(regs, BT431_REG_CRAM_BASE); 34956815Sralph for (k = 0; k < 16; k++) { 35056815Sralph ap = *cursor; 35156815Sralph bp = *(cursor + 16); 35256815Sralph j = 0; 35356815Sralph while (j < 2) { 35456815Sralph out = 0; 35556815Sralph for (i = 0; i < 8; i++) { 35658793Sralph out = (out << 1) | ((bp & 0x1) << 8) | 35758793Sralph (ap & 0x1); 35856815Sralph ap >>= 1; 35956815Sralph bp >>= 1; 36056815Sralph } 36156815Sralph BT431_WRITE_CMAP_AUTOI(regs, out); 36256815Sralph pos++; 36356815Sralph j++; 36456815Sralph } 36556815Sralph while (j < 8) { 36656815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 36756815Sralph pos++; 36856815Sralph j++; 36956815Sralph } 37056815Sralph cursor++; 37156815Sralph } 37256815Sralph while (pos < 512) { 37356815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0); 37456815Sralph pos++; 37556815Sralph } 37656815Sralph } 37756815Sralph 37856815Sralph /* 37956815Sralph * Initialization 38056815Sralph */ 38156815Sralph int 38256815Sralph mfbinit(cp) 38356815Sralph char *cp; 38456815Sralph { 38556815Sralph register struct pmax_fb *fp = &mfbfb; 38656815Sralph 38756815Sralph /* check for no frame buffer */ 38856815Sralph if (badaddr(cp, 4)) 38956815Sralph return (0); 39056815Sralph 39158793Sralph fp->isMono = 0; 39258793Sralph fp->fr_addr = cp + MFB_OFFSET_VRAM; 39358793Sralph fp->fr_chipaddr = cp; 39458974Sralph fp->fr_size = MFB_FB_SIZE; 39557234Sralph /* 39658974Sralph * Must be in Uncached space since the fbuaccess structure is 39758974Sralph * mapped into the user's address space uncached. 39857234Sralph */ 39957234Sralph fp->fbu = (struct fbuaccess *) 40057234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu)); 40156815Sralph fp->posCursor = mfbPosCursor; 40257234Sralph if (tb_kbdmouseconfig(fp)) 40356815Sralph return (0); 40456815Sralph 40556815Sralph /* 40656815Sralph * Initialize the screen. 40756815Sralph */ 40858793Sralph bt431_init(fp->fr_chipaddr + MFB_OFFSET_BT431); 40956815Sralph 41056815Sralph /* 41156815Sralph * Initialize screen info. 41256815Sralph */ 41356815Sralph fp->fbu->scrInfo.max_row = 67; 41456815Sralph fp->fbu->scrInfo.max_col = 80; 41556815Sralph fp->fbu->scrInfo.max_x = 1280; 41656815Sralph fp->fbu->scrInfo.max_y = 1024; 41756815Sralph fp->fbu->scrInfo.max_cur_x = 1279; 41856815Sralph fp->fbu->scrInfo.max_cur_y = 1023; 41956815Sralph fp->fbu->scrInfo.version = 11; 42056815Sralph fp->fbu->scrInfo.mthreshold = 4; 42156815Sralph fp->fbu->scrInfo.mscale = 2; 42256815Sralph fp->fbu->scrInfo.min_cur_x = 0; 42356815Sralph fp->fbu->scrInfo.min_cur_y = 0; 42456815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 42556815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 42656815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 42756815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 42856815Sralph fp->fbu->scrInfo.qe.tcNext = 0; 42956815Sralph 43056815Sralph /* 43156815Sralph * Initialize the color map, the screen, and the mouse. 43256815Sralph */ 43358793Sralph mfbInitColorMap(0); 43456815Sralph mfbScreenInit(); 43556815Sralph fbScroll(fp); 43656815Sralph 43756815Sralph fp->initialized = 1; 43856815Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 43956815Sralph cn_tab.cn_fb = fp; 44056815Sralph return (1); 44156815Sralph } 44256815Sralph 44356815Sralph /* 44456815Sralph * ---------------------------------------------------------------------------- 44556815Sralph * 44656815Sralph * mfbScreenInit -- 44756815Sralph * 44856815Sralph * Initialize the screen. 44956815Sralph * 45056815Sralph * Results: 45156815Sralph * None. 45256815Sralph * 45356815Sralph * Side effects: 45456815Sralph * The screen is initialized. 45556815Sralph * 45656815Sralph * ---------------------------------------------------------------------------- 45756815Sralph */ 45856815Sralph static void 45956815Sralph mfbScreenInit() 46056815Sralph { 46156815Sralph register struct pmax_fb *fp = &mfbfb; 46256815Sralph 46356815Sralph /* 46456815Sralph * Home the cursor. 46556815Sralph * We want an LSI terminal emulation. We want the graphics 46656815Sralph * terminal to scroll from the bottom. So start at the bottom. 46756815Sralph */ 46856815Sralph fp->row = 66; 46956815Sralph fp->col = 0; 47056815Sralph 47156815Sralph /* 47256815Sralph * Load the cursor with the default values 47356815Sralph * 47456815Sralph */ 47556815Sralph mfbLoadCursor(defCursor); 47656815Sralph } 47756815Sralph 47856815Sralph /* 47956815Sralph * ---------------------------------------------------------------------------- 48056815Sralph * 48156815Sralph * RestoreCursorColor -- 48256815Sralph * 48356815Sralph * Routine to restore the color of the cursor. 48456815Sralph * 48556815Sralph * Results: 48656815Sralph * None. 48756815Sralph * 48856815Sralph * Side effects: 48956815Sralph * None. 49056815Sralph * 49156815Sralph * ---------------------------------------------------------------------------- 49256815Sralph */ 49356815Sralph static void 49456815Sralph mfbRestoreCursorColor() 49556815Sralph { 49658793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 49758793Sralph MFB_OFFSET_BT455); 49856815Sralph ColorMap cm; 49958793Sralph u_char fg; 50056815Sralph 50158793Sralph if (cursor_RGB[0] || cursor_RGB[1] || cursor_RGB[2]) 50258793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 50358793Sralph else 50458793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 50556815Sralph cm.index = 8; 50656815Sralph mfbLoadColorMap(&cm); 50756815Sralph cm.index = 9; 50856815Sralph mfbLoadColorMap(&cm); 50956815Sralph 51058793Sralph if (cursor_RGB[3] || cursor_RGB[4] || cursor_RGB[5]) 51158793Sralph fg = 0xf; 51258793Sralph else 51358793Sralph fg = 0; 51458793Sralph regs->addr_ovly = fg; 51556815Sralph MachEmptyWriteBuffer(); 51658793Sralph regs->addr_ovly = fg; 51756815Sralph MachEmptyWriteBuffer(); 51858793Sralph regs->addr_ovly = fg; 51956815Sralph MachEmptyWriteBuffer(); 52056815Sralph } 52156815Sralph 52256815Sralph /* 52356815Sralph * ---------------------------------------------------------------------------- 52456815Sralph * 52556815Sralph * CursorColor -- 52656815Sralph * 52756815Sralph * Set the color of the cursor. 52856815Sralph * 52956815Sralph * Results: 53056815Sralph * None. 53156815Sralph * 53256815Sralph * Side effects: 53356815Sralph * None. 53456815Sralph * 53556815Sralph * ---------------------------------------------------------------------------- 53656815Sralph */ 53756815Sralph static void 53856815Sralph mfbCursorColor(color) 53956815Sralph unsigned int color[]; 54056815Sralph { 54156815Sralph register int i, j; 54256815Sralph 54356815Sralph for (i = 0; i < 6; i++) 54456815Sralph cursor_RGB[i] = (u_char)(color[i] >> 8); 54556815Sralph 54656815Sralph mfbRestoreCursorColor(); 54756815Sralph } 54856815Sralph 54956815Sralph /* 55056815Sralph *---------------------------------------------------------------------- 55156815Sralph * 55256815Sralph * PosCursor -- 55356815Sralph * 55456815Sralph * Postion the cursor. 55556815Sralph * 55656815Sralph * Results: 55756815Sralph * None. 55856815Sralph * 55956815Sralph * Side effects: 56056815Sralph * None. 56156815Sralph * 56256815Sralph *---------------------------------------------------------------------- 56356815Sralph */ 56456815Sralph void 56556815Sralph mfbPosCursor(x, y) 56656815Sralph register int x, y; 56756815Sralph { 56858793Sralph bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr + 56958793Sralph MFB_OFFSET_BT431); 57056815Sralph register struct pmax_fb *fp = &mfbfb; 57156815Sralph 57256815Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 57356815Sralph y = fp->fbu->scrInfo.max_cur_y; 57456815Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 57556815Sralph x = fp->fbu->scrInfo.max_cur_x; 57656815Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 57756815Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 57856815Sralph 57956815Sralph #define lo(v) ((v)&0xff) 58056815Sralph #define hi(v) (((v)&0xf00)>>8) 58156815Sralph 58256815Sralph /* 58356815Sralph * Cx = x + D + H - P 58456815Sralph * P = 37 if 1:1, 52 if 4:1, 57 if 5:1 58556815Sralph * D = pixel skew between outdata and external data 58656815Sralph * H = pixels between HSYNCH falling and active video 58756815Sralph * 58856815Sralph * Cy = y + V - 32 58956815Sralph * V = scanlines between HSYNCH falling, two or more 59056815Sralph * clocks after VSYNCH falling, and active video 59156815Sralph */ 59256815Sralph 59358793Sralph bt431_write_reg(regs, BT431_REG_CXLO, lo(x + 360)); 59456815Sralph BT431_WRITE_REG_AUTOI(regs, hi(x + 360)); 59556815Sralph BT431_WRITE_REG_AUTOI(regs, lo(y + 36)); 59656815Sralph BT431_WRITE_REG_AUTOI(regs, hi(y + 36)); 59756815Sralph } 59856815Sralph 59956815Sralph /* 60056815Sralph * ---------------------------------------------------------------------------- 60156815Sralph * 60256815Sralph * InitColorMap -- 60356815Sralph * 60456815Sralph * Initialize the color map. 60556815Sralph * 60656815Sralph * Results: 60756815Sralph * None. 60856815Sralph * 60956815Sralph * Side effects: 61056815Sralph * The colormap is initialized appropriately. 61156815Sralph * 61256815Sralph * ---------------------------------------------------------------------------- 61356815Sralph */ 61456815Sralph static void 61558793Sralph mfbInitColorMap(blackpix) 61658793Sralph int blackpix; 61756815Sralph { 61856815Sralph ColorMap cm; 61956815Sralph register int i; 62056815Sralph 62156815Sralph cm.index = 0; 62258793Sralph if (blackpix) 62358793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 62458793Sralph else 62558793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 62656815Sralph mfbLoadColorMap(&cm); 62758793Sralph if (blackpix) 62858793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 62958793Sralph else 63058793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff; 63156815Sralph for (i = 1; i < 16; i++) { 63256815Sralph cm.index = i; 63356815Sralph mfbLoadColorMap(&cm); 63456815Sralph } 63556815Sralph 63656815Sralph for (i = 0; i < 3; i++) { 63758793Sralph cursor_RGB[i] = 0; 63856815Sralph cursor_RGB[i + 3] = 0xff; 63956815Sralph } 64056815Sralph mfbRestoreCursorColor(); 64156815Sralph } 64256815Sralph 64356815Sralph /* 64456815Sralph * ---------------------------------------------------------------------------- 64556815Sralph * 64656815Sralph * LoadColorMap -- 64756815Sralph * 64856815Sralph * Load the color map. 64956815Sralph * 65056815Sralph * Results: 65156815Sralph * None. 65256815Sralph * 65356815Sralph * Side effects: 65456815Sralph * The color map is loaded. 65556815Sralph * 65656815Sralph * ---------------------------------------------------------------------------- 65756815Sralph */ 65856815Sralph static void 65956815Sralph mfbLoadColorMap(ptr) 66056815Sralph ColorMap *ptr; 66156815Sralph { 66258793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 66358793Sralph MFB_OFFSET_BT455); 66456815Sralph 66556815Sralph if (ptr->index > 15) 66656815Sralph return; 66756815Sralph 66856815Sralph BT455_SELECT_ENTRY(regs, ptr->index); 66956815Sralph regs->addr_cmap_data = ptr->Entry.red >> 12; 67056815Sralph MachEmptyWriteBuffer(); 67156815Sralph regs->addr_cmap_data = ptr->Entry.green >> 12; 67256815Sralph MachEmptyWriteBuffer(); 67356815Sralph regs->addr_cmap_data = ptr->Entry.blue >> 12; 67456815Sralph MachEmptyWriteBuffer(); 67556815Sralph } 67656815Sralph 67756815Sralph /* 67856815Sralph * Video on/off state. 67956815Sralph */ 68056815Sralph static struct vstate { 68156815Sralph u_char color0[6]; /* saved color map entry zero */ 68256815Sralph u_char off; /* TRUE if display is off */ 68358793Sralph u_char cursor[6]; /* saved cursor color */ 68456815Sralph } vstate; 68556815Sralph 68656815Sralph /* 68756815Sralph * ---------------------------------------------------------------------------- 68856815Sralph * 68956815Sralph * bt455_video_on 69056815Sralph * 69156815Sralph * Enable the video display. 69256815Sralph * 69356815Sralph * Results: 69456815Sralph * None. 69556815Sralph * 69656815Sralph * Side effects: 69756815Sralph * The display is enabled. 69856815Sralph * 69956815Sralph * ---------------------------------------------------------------------------- 70056815Sralph */ 70156815Sralph static void 70256815Sralph bt455_video_on() 70356815Sralph { 70458793Sralph register int i; 70558793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 70658793Sralph MFB_OFFSET_BT455); 70756815Sralph 70856815Sralph if (!vstate.off) 70956815Sralph return; 71056815Sralph 71156815Sralph /* restore old color map entry zero */ 71256815Sralph BT455_SELECT_ENTRY(regs, 0); 71358793Sralph for (i = 0; i < 6; i++) { 71458793Sralph regs->addr_cmap_data = vstate.color0[i]; 71558793Sralph MachEmptyWriteBuffer(); 71658793Sralph cursor_RGB[i] = vstate.cursor[i]; 71758793Sralph } 71858793Sralph mfbRestoreCursorColor(); 71956815Sralph vstate.off = 0; 72056815Sralph } 72156815Sralph 72256815Sralph /* 72356815Sralph * ---------------------------------------------------------------------------- 72456815Sralph * 72556815Sralph * bt455_video_off 72656815Sralph * 72756815Sralph * Disable the video display. 72856815Sralph * 72956815Sralph * Results: 73056815Sralph * None. 73156815Sralph * 73256815Sralph * Side effects: 73356815Sralph * The display is disabled. 73456815Sralph * 73556815Sralph * ---------------------------------------------------------------------------- 73656815Sralph */ 73756815Sralph static void 73856815Sralph bt455_video_off() 73956815Sralph { 74058793Sralph register int i; 74158793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr + 74258793Sralph MFB_OFFSET_BT455); 74356815Sralph ColorMap cm; 74456815Sralph 74556815Sralph if (vstate.off) 74656815Sralph return; 74756815Sralph 74856815Sralph /* save old color map entry zero */ 74956815Sralph BT455_SELECT_ENTRY(regs, 0); 75058793Sralph for (i = 0; i < 6; i++) { 75158793Sralph vstate.color0[i] = regs->addr_cmap_data; 75258793Sralph vstate.cursor[i] = cursor_RGB[i]; 75358793Sralph cursor_RGB[i] = 0; 75458793Sralph } 75556815Sralph 75656815Sralph /* set color map entry zero to zero */ 75756815Sralph cm.index = 0; 75856815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0; 75956815Sralph mfbLoadColorMap(&cm); 76056815Sralph cm.index = 1; 76156815Sralph mfbLoadColorMap(&cm); 76256815Sralph 76358793Sralph mfbRestoreCursorColor(); 76456815Sralph vstate.off = 1; 76556815Sralph } 76656815Sralph 76756815Sralph /* 76856815Sralph * mfb keyboard and mouse input. Just punt to the generic ones in fb.c 76956815Sralph */ 77056815Sralph void 77156815Sralph mfbKbdEvent(ch) 77256815Sralph int ch; 77356815Sralph { 77456815Sralph fbKbdEvent(ch, &mfbfb); 77556815Sralph } 77656815Sralph 77756815Sralph void 77856815Sralph mfbMouseEvent(newRepPtr) 77956815Sralph MouseReport *newRepPtr; 78056815Sralph { 78156815Sralph fbMouseEvent(newRepPtr, &mfbfb); 78256815Sralph } 78356815Sralph 78456815Sralph void 78556815Sralph mfbMouseButtons(newRepPtr) 78656815Sralph MouseReport *newRepPtr; 78756815Sralph { 78856815Sralph fbMouseButtons(newRepPtr, &mfbfb); 78956815Sralph } 79056815Sralph 79156815Sralph /* 79256815Sralph * Configure the mouse and keyboard based on machine type 79356815Sralph */ 79456815Sralph static void 79556815Sralph mfbConfigMouse() 79656815Sralph { 79756815Sralph int s; 79856815Sralph 79956815Sralph s = spltty(); 80056815Sralph switch (pmax_boardtype) { 80156815Sralph #if NDC > 0 80256815Sralph case DS_3MAX: 80356815Sralph dcDivertXInput = mfbKbdEvent; 80456815Sralph dcMouseEvent = mfbMouseEvent; 80556815Sralph dcMouseButtons = mfbMouseButtons; 80656815Sralph break; 80756815Sralph #endif 80856815Sralph #if NSCC > 1 80956815Sralph case DS_3MIN: 81056815Sralph sccDivertXInput = mfbKbdEvent; 81156815Sralph sccMouseEvent = mfbMouseEvent; 81256815Sralph sccMouseButtons = mfbMouseButtons; 81356815Sralph break; 81456815Sralph #endif 81556815Sralph #if NDTOP > 0 81656815Sralph case DS_MAXINE: 81756815Sralph dtopDivertXInput = mfbKbdEvent; 81856815Sralph dtopMouseEvent = mfbMouseEvent; 81956815Sralph dtopMouseButtons = mfbMouseButtons; 82056815Sralph break; 82156815Sralph #endif 82256815Sralph default: 82356815Sralph printf("Can't configure mouse/keyboard\n"); 82456815Sralph }; 82556815Sralph splx(s); 82656815Sralph } 82756815Sralph 82856815Sralph /* 82956815Sralph * and deconfigure them 83056815Sralph */ 83156815Sralph static void 83256815Sralph mfbDeconfigMouse() 83356815Sralph { 83456815Sralph int s; 83556815Sralph 83656815Sralph s = spltty(); 83756815Sralph switch (pmax_boardtype) { 83856815Sralph #if NDC > 0 83956815Sralph case DS_3MAX: 84056815Sralph dcDivertXInput = (void (*)())0; 84156815Sralph dcMouseEvent = (void (*)())0; 84256815Sralph dcMouseButtons = (void (*)())0; 84356815Sralph break; 84456815Sralph #endif 84556815Sralph #if NSCC > 1 84656815Sralph case DS_3MIN: 84756815Sralph sccDivertXInput = (void (*)())0; 84856815Sralph sccMouseEvent = (void (*)())0; 84956815Sralph sccMouseButtons = (void (*)())0; 85056815Sralph break; 85156815Sralph #endif 85256815Sralph #if NDTOP > 0 85356815Sralph case DS_MAXINE: 85456815Sralph dtopDivertXInput = (void (*)())0; 85556815Sralph dtopMouseEvent = (void (*)())0; 85656815Sralph dtopMouseButtons = (void (*)())0; 85756815Sralph break; 85856815Sralph #endif 85956815Sralph default: 86056815Sralph printf("Can't deconfigure mouse/keyboard\n"); 86156815Sralph }; 86256815Sralph } 86356815Sralph 86456815Sralph /* 86556815Sralph * Generic register access 86656815Sralph */ 86756815Sralph static void 86856815Sralph bt431_select_reg(regs, regno) 86956815Sralph bt431_regmap_t *regs; 87056815Sralph { 87156815Sralph regs->addr_lo = SET_VALUE(regno & 0xff); 87256815Sralph regs->addr_hi = SET_VALUE((regno >> 8) & 0xff); 87356815Sralph MachEmptyWriteBuffer(); 87456815Sralph } 87556815Sralph 87656815Sralph static void 87756815Sralph bt431_write_reg(regs, regno, val) 87856815Sralph bt431_regmap_t *regs; 87956815Sralph { 88056815Sralph bt431_select_reg(regs, regno); 88156815Sralph regs->addr_reg = SET_VALUE(val); 88256815Sralph MachEmptyWriteBuffer(); 88356815Sralph } 88456815Sralph 88556815Sralph static u_char 88656815Sralph bt431_read_reg(regs, regno) 88756815Sralph bt431_regmap_t *regs; 88856815Sralph { 88956815Sralph bt431_select_reg(regs, regno); 89056815Sralph return (GET_VALUE(regs->addr_reg)); 89156815Sralph } 89256815Sralph 89356815Sralph static void 89456815Sralph bt431_init(regs) 89556815Sralph bt431_regmap_t *regs; 89656815Sralph { 89756815Sralph register int i; 89856815Sralph 89956815Sralph /* use 4:1 input mux */ 90056815Sralph bt431_write_reg(regs, BT431_REG_CMD, 90156815Sralph BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS| 90256815Sralph BT431_CMD_4_1_MUX|BT431_CMD_THICK_1); 90356815Sralph 90456815Sralph /* home cursor */ 90556815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 90656815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 90756815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 90856815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 90956815Sralph 91056815Sralph /* no crosshair window */ 91156815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91256815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91356815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 91456815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00); 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 } 92056815Sralph #endif /* NMFB */ 921