📄 cfb.c
字号:
/*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Ralph Campbell and Rick Macklem. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)cfb.c 8.1 (Berkeley) 6/10/93 *//* * devGraphics.c -- * * This file contains machine-dependent routines for the graphics device. * * Copyright (C) 1989 Digital Equipment Corporation. * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appears in all copies. * Digital Equipment Corporation makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; *//* * Mach Operating System * Copyright (c) 1991,1990,1989 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. */#include <cfb.h>#if NCFB > 0#include <sys/param.h>#include <sys/time.h>#include <sys/kernel.h>#include <sys/ioctl.h>#include <sys/file.h>#include <sys/errno.h>#include <sys/proc.h>#include <sys/mman.h>#include <vm/vm.h>#include <machine/machConst.h>#include <machine/pmioctl.h>#include <pmax/pmax/maxine.h>#include <pmax/pmax/cons.h>#include <pmax/pmax/pmaxtype.h>#include <pmax/dev/device.h>#include <pmax/dev/cfbreg.h>#include <pmax/dev/fbreg.h>#include <dc.h>#include <dtop.h>#include <scc.h>#define PMAX /* enable /dev/pm compatibility *//* * These need to be mapped into user space. */struct fbuaccess cfbu;struct pmax_fb cfbfb;/* * Forward references. */static void cfbScreenInit();static void cfbLoadCursor();static void cfbRestoreCursorColor();static void cfbCursorColor();void cfbPosCursor();static void cfbInitColorMap();static void cfbLoadColorMap();static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off();static void bt459_select_reg(), bt459_write_reg();static u_char bt459_read_reg();static void cfbConfigMouse(), cfbDeconfigMouse();void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons();#if NDC > 0extern void (*dcDivertXInput)();extern void (*dcMouseEvent)();extern void (*dcMouseButtons)();#endif#if NSCC > 0extern void (*sccDivertXInput)();extern void (*sccMouseEvent)();extern void (*sccMouseButtons)();#endif#if NDTOP > 0extern void (*dtopDivertXInput)();extern void (*dtopMouseEvent)();extern void (*dtopMouseButtons)();#endifextern int pmax_boardtype;extern u_short defCursor[32];extern struct consdev cn_tab;int cfbprobe();struct driver cfbdriver = { "cfb", cfbprobe, 0, 0,};#define CFB_OFFSET_VRAM 0x0 /* from module's base */#define CFB_OFFSET_BT459 0x200000 /* Bt459 registers */#define CFB_OFFSET_IREQ 0x300000 /* Interrupt req. control */#define CFB_OFFSET_ROM 0x380000 /* Diagnostic ROM */#define CFB_OFFSET_RESET 0x3c0000 /* Bt459 resets on writes */#define CFB_FB_SIZE 0x100000 /* frame buffer size *//* * Test to see if device is present. * Return true if found and initialized ok. *//*ARGSUSED*/cfbprobe(cp) register struct pmax_ctlr *cp;{ register struct pmax_fb *fp = &cfbfb; if (!fp->initialized && !cfbinit(cp->pmax_addr)) return (0); printf("cfb0 (color display)\n"); return (1);}/*ARGSUSED*/cfbopen(dev, flag) dev_t dev; int flag;{ register struct pmax_fb *fp = &cfbfb; int s; if (!fp->initialized) return (ENXIO); if (fp->GraphicsOpen) return (EBUSY); fp->GraphicsOpen = 1; cfbInitColorMap(); /* * Set up event queue for later */ fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; fp->fbu->scrInfo.qe.tcNext = 0; fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); cfbConfigMouse(); return (0);}/*ARGSUSED*/cfbclose(dev, flag) dev_t dev; int flag;{ register struct pmax_fb *fp = &cfbfb; int s; if (!fp->GraphicsOpen) return (EBADF); fp->GraphicsOpen = 0; cfbInitColorMap(); cfbDeconfigMouse(); cfbScreenInit(); bzero((caddr_t)fp->fr_addr, 1024 * 864); cfbPosCursor(fp->col * 8, fp->row * 15); return (0);}/*ARGSUSED*/cfbioctl(dev, cmd, data, flag, p) dev_t dev; caddr_t data; struct proc *p;{ register struct pmax_fb *fp = &cfbfb; int s; switch (cmd) { case QIOCGINFO: return (fbmmap(fp, dev, data, p)); case QIOCPMSTATE: /* * Set mouse state. */ fp->fbu->scrInfo.mouse = *(pmCursor *)data; cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); break; case QIOCINIT: /* * Initialize the screen. */ cfbScreenInit(); break; case QIOCKPCMD: { pmKpCmd *kpCmdPtr; unsigned char *cp; kpCmdPtr = (pmKpCmd *)data; if (kpCmdPtr->nbytes == 0) kpCmdPtr->cmd |= 0x80; if (!fp->GraphicsOpen) kpCmdPtr->cmd |= 1; (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); cp = &kpCmdPtr->par[0]; for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { if (kpCmdPtr->nbytes == 1) *cp |= 0x80; (*fp->KBDPutc)(fp->kbddev, (int)*cp); } break; } case QIOCADDR: *(PM_Info **)data = &fp->fbu->scrInfo; break; case QIOWCURSOR: cfbLoadCursor((unsigned short *)data); break; case QIOWCURSORCOLOR: cfbCursorColor((unsigned int *)data); break; case QIOSETCMAP: cfbLoadColorMap((ColorMap *)data); break; case QIOKERNLOOP: cfbConfigMouse(); break; case QIOKERNUNLOOP: cfbDeconfigMouse(); break; case QIOVIDEOON: cfbRestoreCursorColor(); bt459_video_on(); break; case QIOVIDEOOFF: bt459_video_off(); break; default: printf("cfb0: Unknown ioctl command %x\n", cmd); return (EINVAL); } return (0);}cfbselect(dev, flag, p) dev_t dev; int flag; struct proc *p;{ struct pmax_fb *fp = &cfbfb; switch (flag) { case FREAD: if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) return (1); selrecord(p, &fp->selp); break; } return (0);}/* * Return the physical page number that corresponds to byte offset 'off'. *//*ARGSUSED*/cfbmap(dev, off, prot) dev_t dev;{ int len; len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu)); if (off < len) return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off); off -= len; if (off >= cfbfb.fr_size) return (-1); return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off);}static u_char cursor_RGB[6]; /* cursor color 2 & 3 *//* * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM * defines a 64x64 cursor. If the bt459 does not map the cursor RAM * this way, this code is Screwed! */static voidcfbLoadCursor(cursor) u_short *cursor;{#ifdef PMAX register int i, j, k, pos; register u_short ap, bp, out; /* * Fill in the cursor sprite using the A and B planes, as provided * for the pmax. * XXX This will have to change when the X server knows that this * is not a pmax display. */ pos = 0; for (k = 0; k < 16; k++) { ap = *cursor; bp = *(cursor + 16); j = 0; while (j < 4) { out = 0; for (i = 0; i < 4; i++) {#ifndef CURSOR_EB out = (out << 2) | ((ap & 0x1) << 1) | (bp & 0x1);#else out = ((out >> 2) & 0x3f) | ((ap & 0x1) << 7) | ((bp & 0x1) << 6);#endif ap >>= 1; bp >>= 1; } bt459_set_cursor_ram(pos, out); pos++; j++; } while (j < 16) { bt459_set_cursor_ram(pos, 0); pos++; j++; } cursor++; } while (pos < 1024) { bt459_set_cursor_ram(pos, 0); pos++; }#endif /* PMAX */}/* * Set a cursor ram value. */static voidbt459_set_cursor_ram(pos, val) int pos; register u_char val;{ register bt459_regmap_t *regs = (bt459_regmap_t *) (cfbfb.fr_addr + CFB_OFFSET_BT459); register int cnt; u_char nval; cnt = 0; do { bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val); nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos); } while (val != nval && ++cnt < 10);}/* * Generic register access */static voidbt459_select_reg(regs, regno) bt459_regmap_t *regs;{ regs->addr_lo = regno; regs->addr_hi = regno >> 8; MachEmptyWriteBuffer();}static voidbt459_write_reg(regs, regno, val) bt459_regmap_t *regs;{ regs->addr_lo = regno; regs->addr_hi = regno >> 8; MachEmptyWriteBuffer(); regs->addr_reg = val; MachEmptyWriteBuffer();}static u_charbt459_read_reg(regs, regno) bt459_regmap_t *regs;{ regs->addr_lo = regno; regs->addr_hi = regno >> 8; MachEmptyWriteBuffer(); return (regs->addr_reg);}/* * Initialization */intcfbinit(cp) char *cp;{ register bt459_regmap_t *regs; register struct pmax_fb *fp = &cfbfb; /* check for no frame buffer */ if (badaddr(cp, 4)) return (0); fp->isMono = 0; fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM); fp->fr_size = CFB_FB_SIZE; /* * Must be in Uncached space since the fbuaccess structure is * mapped into the user's address space uncached. */ fp->fbu = (struct fbuaccess *) MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu)); fp->posCursor = cfbPosCursor; if (tb_kbdmouseconfig(fp)) return (0); /* * Initialize the screen. */ regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459); if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a) return (0); /* Reset the chip */ *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -