⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgsix.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
			if (error)				return (error);		} else {			p->cmap.index = 0;			p->cmap.count = 2;		}		/* end ugh */		break;	case FBIOSCURSOR:		/*		 * For setcmap and setshape, verify parameters, so that		 * we do not get halfway through an update and then crap		 * out with the software state screwed up.		 */		v = p->set;		if (v & FB_CUR_SETCMAP) {			/*			 * This use of a temporary copy of the cursor			 * colormap is not terribly efficient, but these			 * copies are small (8 bytes)...			 */			tcm = cc->cc_color;			error = bt_putcmap(&p->cmap, (union bt_cmap *)&tcm, 2);			if (error)				return (error);		}		if (v & FB_CUR_SETSHAPE) {			if ((u_int)p->size.x > 32 || (u_int)p->size.y > 32)				return (EINVAL);			count = p->size.y * 32 / NBBY;			if (!useracc(p->image, count, B_READ) ||			    !useracc(p->mask, count, B_READ))				return (EFAULT);		}		/* parameters are OK; do it */		if (v & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)) {			if (v & FB_CUR_SETCUR)				cc->cc_enable = p->enable;			if (v & FB_CUR_SETPOS)				cc->cc_pos = p->pos;			if (v & FB_CUR_SETHOT)				cc->cc_hot = p->hot;			cg6_setcursor(sc);		}		if (v & FB_CUR_SETCMAP) {			cc->cc_color = tcm;			cg6_loadomap(sc); /* XXX defer to vertical retrace */		}		if (v & FB_CUR_SETSHAPE) {			cc->cc_size = p->size;			count = p->size.y * 32 / NBBY;			bzero((caddr_t)cc->cc_bits, sizeof cc->cc_bits);			bcopy(p->mask, (caddr_t)cc->cc_bits[0], count);			bcopy(p->image, (caddr_t)cc->cc_bits[1], count);			cg6_loadcursor(sc);		}		break;#undef p#undef cc	case FBIOGCURPOS:		*(struct fbcurpos *)data = sc->sc_cursor.cc_pos;		break;	case FBIOSCURPOS:		sc->sc_cursor.cc_pos = *(struct fbcurpos *)data;		cg6_setcursor(sc);		break;	case FBIOGCURMAX:		/* max cursor size is 32x32 */		((struct fbcurpos *)data)->x = 32;		((struct fbcurpos *)data)->y = 32;		break;	default:#ifdef DEBUG		log(LOG_NOTICE, "cgsixioctl(%x) (%s[%d])\n", cmd,		    p->p_comm, p->p_pid);#endif		return (ENOTTY);	}	return (0);}/* * Clean up hardware state (e.g., after bootup or after X crashes). */static voidcg6_reset(sc)	register struct cgsix_softc *sc;{	register volatile struct cg6_tec_xxx *tec;	register int fhc;	register volatile struct bt_regs *bt;	/* hide the cursor, just in case */	sc->sc_thc->thc_cursxy = (THC_CURSOFF << 16) | THC_CURSOFF;	/* turn off frobs in transform engine (makes X11 work) */	tec = sc->sc_tec;	tec->tec_mv = 0;	tec->tec_clip = 0;	tec->tec_vdc = 0;	/* take care of hardware bugs in old revisions */	if (sc->sc_fhcrev < 5) {		/*		 * Keep current resolution; set cpu to 68020, set test		 * window (size 1Kx1K), and for rev 1, disable dest cache.		 */		fhc = (*sc->sc_fhc & FHC_RES_MASK) | FHC_CPU_68020 |		    FHC_TEST |		    (11 << FHC_TESTX_SHIFT) | (11 << FHC_TESTY_SHIFT);		if (sc->sc_fhcrev < 2)			fhc |= FHC_DST_DISABLE;		*sc->sc_fhc = fhc;	}	/* Enable cursor in Brooktree DAC. */	bt = sc->sc_bt;	bt->bt_addr = 0x06 << 24;	bt->bt_ctrl |= 0x03 << 24;}static voidcg6_setcursor(sc)	register struct cgsix_softc *sc;{	/* we need to subtract the hot-spot value here */#define COORD(f) (sc->sc_cursor.cc_pos.f - sc->sc_cursor.cc_hot.f)	sc->sc_thc->thc_cursxy = sc->sc_cursor.cc_enable ?	    ((COORD(x) << 16) | (COORD(y) & 0xffff)) :	    (THC_CURSOFF << 16) | THC_CURSOFF;#undef COORD}static voidcg6_loadcursor(sc)	register struct cgsix_softc *sc;{	register volatile struct cg6_thc *thc;	register u_int edgemask, m;	register int i;	/*	 * Keep the top size.x bits.  Here we *throw out* the top	 * size.x bits from an all-one-bits word, introducing zeros in	 * the top size.x bits, then invert all the bits to get what	 * we really wanted as our mask.  But this fails if size.x is	 * 32---a sparc uses only the low 5 bits of the shift count---	 * so we have to special case that.	 */	edgemask = ~0;	if (sc->sc_cursor.cc_size.x < 32)		edgemask = ~(edgemask >> sc->sc_cursor.cc_size.x);	thc = sc->sc_thc;	for (i = 0; i < 32; i++) {		m = sc->sc_cursor.cc_bits[0][i] & edgemask;		thc->thc_cursmask[i] = m;		thc->thc_cursbits[i] = m & sc->sc_cursor.cc_bits[1][i];	}}/* * Load a subset of the current (new) colormap into the color DAC. */static voidcg6_loadcmap(sc, start, ncolors)	register struct cgsix_softc *sc;	register int start, ncolors;{	register volatile struct bt_regs *bt;	register u_int *ip, i;	register int count;	ip = &sc->sc_cmap.cm_chip[BT_D4M3(start)];	/* start/4 * 3 */	count = BT_D4M3(start + ncolors - 1) - BT_D4M3(start) + 3;	bt = sc->sc_bt;	bt->bt_addr = BT_D4M4(start) << 24;	while (--count >= 0) {		i = *ip++;		/* hardware that makes one want to pound boards with hammers */		bt->bt_cmap = i;		bt->bt_cmap = i << 8;		bt->bt_cmap = i << 16;		bt->bt_cmap = i << 24;	}}/* * Load the cursor (overlay `foreground' and `background') colors. */static voidcg6_loadomap(sc)	register struct cgsix_softc *sc;{	register volatile struct bt_regs *bt;	register u_int i;	bt = sc->sc_bt;	bt->bt_addr = 0x01 << 24;	/* set background color */	i = sc->sc_cursor.cc_color.cm_chip[0];	bt->bt_omap = i;		/* R */	bt->bt_omap = i << 8;		/* G */	bt->bt_omap = i << 16;		/* B */	bt->bt_addr = 0x03 << 24;	/* set foreground color */	bt->bt_omap = i << 24;		/* R */	i = sc->sc_cursor.cc_color.cm_chip[1];	bt->bt_omap = i;		/* G */	bt->bt_omap = i << 8;		/* B */}static voidcg6_unblank(dev)	struct device *dev;{	struct cgsix_softc *sc = (struct cgsix_softc *)dev;	if (sc->sc_blanked) {		sc->sc_blanked = 0;		sc->sc_thc->thc_misc |= THC_MISC_VIDEN;	}}/* XXX the following should be moved to a "user interface" header *//* * Base addresses at which users can mmap() the various pieces of a cg6. * Note that although the Brooktree color registers do not occupy 8K, * the X server dies if we do not allow it to map 8K there (it just maps * from 0x70000000 forwards, as a contiguous chunk). */#define	CG6_USER_FBC	0x70000000#define	CG6_USER_TEC	0x70001000#define	CG6_USER_BTREGS	0x70002000#define	CG6_USER_FHC	0x70004000#define	CG6_USER_THC	0x70005000#define	CG6_USER_ROM	0x70006000#define	CG6_USER_RAM	0x70016000#define	CG6_USER_DHC	0x80000000struct mmo {	u_int	mo_uaddr;	/* user (virtual) address */	u_int	mo_size;	/* size, or 0 for video ram size */	u_int	mo_physoff;	/* offset from sc_physadr */};/* * Return the address that would map the given device at the given * offset, allowing for the given protection, or return -1 for error. * * XXX	needs testing against `demanding' applications (e.g., aviator) */intcgsixmap(dev, off, prot)	dev_t dev;	int off, prot;{	register struct cgsix_softc *sc = cgsixcd.cd_devs[minor(dev)];	register struct mmo *mo;	register u_int u, sz;#define	O(memb) ((u_int)(&((struct cg6_layout *)0)->memb))	static struct mmo mmo[] = {		{ CG6_USER_RAM, 0, O(cg6_ram) },		/* do not actually know how big most of these are! */		{ CG6_USER_FBC, 1, O(cg6_fbc_un) },		{ CG6_USER_TEC, 1, O(cg6_tec_un) },		{ CG6_USER_BTREGS, 8192 /* XXX */, O(cg6_bt_un) },		{ CG6_USER_FHC, 1, O(cg6_fhc_un) },		{ CG6_USER_THC, sizeof(struct cg6_thc), O(cg6_thc_un) },		{ CG6_USER_ROM, 65536, O(cg6_rom_un) },		{ CG6_USER_DHC, 1, O(cg6_dhc_un) },	};#define NMMO (sizeof mmo / sizeof *mmo)	if (off & PGOFSET)		panic("cgsixmap");	/*	 * Entries with size 0 map video RAM (i.e., the size in fb data).	 *	 * Since we work in pages, the fact that the map offset table's	 * sizes are sometimes bizarre (e.g., 1) is effectively ignored:	 * one byte is as good as one page.	 */	for (mo = mmo; mo < &mmo[NMMO]; mo++) {		if ((u_int)off < mo->mo_uaddr)			continue;		u = off - mo->mo_uaddr;		sz = mo->mo_size ? mo->mo_size : sc->sc_fb.fb_type.fb_size;		if (u < sz)			return ((int)sc->sc_physadr + u + mo->mo_physoff +			    PMAP_OBIO + PMAP_NC);	}#ifdef DEBUG	{	  register struct proc *p = curproc;	/* XXX */	  log(LOG_NOTICE, "cgsixmap(%x) (%s[%d])\n", off, p->p_comm, p->p_pid);	}#endif	return (-1);	/* not a user-map offset */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -