e07f0b9362
copyin() or copyout(). uvm_useracc() tells us whether the mapping permissions allow access to the desired part of an address space, and many callers assume that this is the same as knowing whether an attempt to access that part of the address space will succeed. however, access to user space can fail for reasons other than insufficient permission, most notably that paging in any non-resident data can fail due to i/o errors. most of the callers of uvm_useracc() make the above incorrect assumption. the rest are all misguided optimizations, which optimize for the case where an operation will fail. we'd rather optimize for operations succeeding, in which case we should just attempt the access and handle failures due to insufficient permissions the same way we handle i/o errors. since there appear to be no good uses of uvm_useracc(), we'll just remove it.
615 lines
16 KiB
C
615 lines
16 KiB
C
/* $NetBSD: bt485.c,v 1.10 2003/11/13 03:09:29 chs Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
|
|
* All rights reserved.
|
|
*
|
|
* Author: Chris G. Demetriou
|
|
*
|
|
* 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 "AS IS"
|
|
* 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.
|
|
*/
|
|
|
|
/* This code was derived from and originally located in sys/dev/pci/
|
|
* NetBSD: tga_bt485.c,v 1.4 1999/03/24 05:51:21 mrg Exp
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: bt485.c,v 1.10 2003/11/13 03:09:29 chs Exp $");
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/device.h>
|
|
#include <sys/buf.h>
|
|
#include <sys/kernel.h>
|
|
#include <sys/malloc.h>
|
|
|
|
#include <uvm/uvm_extern.h>
|
|
|
|
#include <dev/pci/pcivar.h>
|
|
#include <dev/ic/bt485reg.h>
|
|
#include <dev/ic/bt485var.h>
|
|
#include <dev/ic/ramdac.h>
|
|
|
|
#include <dev/wscons/wsconsio.h>
|
|
|
|
/*
|
|
* Functions exported via the RAMDAC configuration table.
|
|
*/
|
|
void bt485_init __P((struct ramdac_cookie *));
|
|
int bt485_set_cmap __P((struct ramdac_cookie *,
|
|
struct wsdisplay_cmap *));
|
|
int bt485_get_cmap __P((struct ramdac_cookie *,
|
|
struct wsdisplay_cmap *));
|
|
int bt485_set_cursor __P((struct ramdac_cookie *,
|
|
struct wsdisplay_cursor *));
|
|
int bt485_get_cursor __P((struct ramdac_cookie *,
|
|
struct wsdisplay_cursor *));
|
|
int bt485_set_curpos __P((struct ramdac_cookie *,
|
|
struct wsdisplay_curpos *));
|
|
int bt485_get_curpos __P((struct ramdac_cookie *,
|
|
struct wsdisplay_curpos *));
|
|
int bt485_get_curmax __P((struct ramdac_cookie *,
|
|
struct wsdisplay_curpos *));
|
|
|
|
/* XXX const */
|
|
struct ramdac_funcs bt485_funcsstruct = {
|
|
"Bt485",
|
|
bt485_register,
|
|
bt485_init,
|
|
bt485_set_cmap,
|
|
bt485_get_cmap,
|
|
bt485_set_cursor,
|
|
bt485_get_cursor,
|
|
bt485_set_curpos,
|
|
bt485_get_curpos,
|
|
bt485_get_curmax,
|
|
NULL, /* check_curcmap; not needed */
|
|
NULL, /* set_curcmap; not needed */
|
|
NULL, /* get_curcmap; not needed */
|
|
NULL, /* no dot clock to set */
|
|
};
|
|
|
|
/*
|
|
* Private data.
|
|
*/
|
|
struct bt485data {
|
|
void *cookie; /* This is what is passed
|
|
* around, and is probably
|
|
* struct tga_devconfig *
|
|
*/
|
|
|
|
int (*ramdac_sched_update) __P((void *, void (*)(void *)));
|
|
void (*ramdac_wr) __P((void *, u_int, u_int8_t));
|
|
u_int8_t (*ramdac_rd) __P((void *, u_int));
|
|
|
|
int changed; /* what changed; see below */
|
|
int curenb; /* cursor enabled */
|
|
struct wsdisplay_curpos curpos; /* current cursor position */
|
|
struct wsdisplay_curpos curhot; /* cursor hotspot */
|
|
char curcmap_r[2]; /* cursor colormap */
|
|
char curcmap_g[2];
|
|
char curcmap_b[2];
|
|
struct wsdisplay_curpos cursize; /* current cursor size */
|
|
char curimage[512]; /* cursor image data */
|
|
char curmask[512]; /* cursor mask data */
|
|
char cmap_r[256]; /* colormap */
|
|
char cmap_g[256];
|
|
char cmap_b[256];
|
|
};
|
|
|
|
#define DATA_ENB_CHANGED 0x01 /* cursor enable changed */
|
|
#define DATA_CURCMAP_CHANGED 0x02 /* cursor colormap changed */
|
|
#define DATA_CURSHAPE_CHANGED 0x04 /* cursor size, image, mask changed */
|
|
#define DATA_CMAP_CHANGED 0x08 /* colormap changed */
|
|
#define DATA_ALL_CHANGED 0x0f
|
|
|
|
#define CURSOR_MAX_SIZE 64
|
|
|
|
/*
|
|
* Internal functions.
|
|
*/
|
|
inline void bt485_wr_i __P((struct bt485data *, u_int8_t, u_int8_t));
|
|
inline u_int8_t bt485_rd_i __P((struct bt485data *, u_int8_t));
|
|
void bt485_update __P((void *));
|
|
void bt485_update_curpos __P((struct bt485data *));
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
* Functions exported via the RAMDAC configuration table.
|
|
*/
|
|
|
|
struct ramdac_funcs *
|
|
bt485_funcs(void)
|
|
{
|
|
return &bt485_funcsstruct;
|
|
}
|
|
|
|
struct ramdac_cookie *
|
|
bt485_register(v, sched_update, wr, rd)
|
|
void *v;
|
|
int (*sched_update)(void *, void (*)(void *));
|
|
void (*wr)(void *, u_int, u_int8_t);
|
|
u_int8_t (*rd)(void *, u_int);
|
|
{
|
|
struct bt485data *data;
|
|
/*
|
|
* XXX -- comment out of date. rcd.
|
|
* If we should allocate a new private info struct, do so.
|
|
* Otherwise, use the one we have (if it's there), or
|
|
* use the temporary one on the stack.
|
|
*/
|
|
data = malloc(sizeof *data, M_DEVBUF, M_WAITOK);
|
|
/* XXX -- if !data */
|
|
data->cookie = v;
|
|
data->ramdac_sched_update = sched_update;
|
|
data->ramdac_wr = wr;
|
|
data->ramdac_rd = rd;
|
|
return (struct ramdac_cookie *)data;
|
|
}
|
|
|
|
/*
|
|
* This function exists solely to provide a means to init
|
|
* the RAMDAC without first registering. It is useful for
|
|
* initializing the console early on.
|
|
*/
|
|
void
|
|
bt485_cninit(v, sched_update, wr, rd)
|
|
void *v;
|
|
int (*sched_update)(void *, void (*)(void *));
|
|
void (*wr)(void *, u_int, u_int8_t);
|
|
u_int8_t (*rd)(void *, u_int);
|
|
{
|
|
struct bt485data tmp, *data = &tmp;
|
|
data->cookie = v;
|
|
data->ramdac_sched_update = sched_update;
|
|
data->ramdac_wr = wr;
|
|
data->ramdac_rd = rd;
|
|
bt485_init((struct ramdac_cookie *)data);
|
|
}
|
|
|
|
void
|
|
bt485_init(rc)
|
|
struct ramdac_cookie *rc;
|
|
{
|
|
u_int8_t regval;
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
int i;
|
|
|
|
/*
|
|
* Init the BT485 for normal operation.
|
|
*/
|
|
|
|
/*
|
|
* Allow indirect register access. (Actually, this is
|
|
* already enabled. In fact, if it is _disabled_, for
|
|
* some reason the monitor appears to lose sync!!! (?!?!)
|
|
*/
|
|
regval = data->ramdac_rd(data->cookie, BT485_REG_COMMAND_0);
|
|
regval |= 0x80;
|
|
/*
|
|
* Set the RAMDAC to 8 bit resolution, rather than 6 bit
|
|
* resolution.
|
|
*/
|
|
regval |= 0x02;
|
|
data->ramdac_wr(data->cookie, BT485_REG_COMMAND_0, regval);
|
|
|
|
/* Set the RAMDAC to 8BPP (no interestion options). */
|
|
data->ramdac_wr(data->cookie, BT485_REG_COMMAND_1, 0x40);
|
|
|
|
/* Disable the cursor (for now) */
|
|
regval = data->ramdac_rd(data->cookie, BT485_REG_COMMAND_2);
|
|
regval &= ~0x03;
|
|
regval |= 0x24;
|
|
data->ramdac_wr(data->cookie, BT485_REG_COMMAND_2, regval);
|
|
|
|
/* Use a 64x64x2 cursor */
|
|
regval = bt485_rd_i(data, BT485_IREG_COMMAND_3);
|
|
regval |= 0x04;
|
|
regval |= 0x08;
|
|
bt485_wr_i(data, BT485_IREG_COMMAND_3, regval);
|
|
|
|
/* Set the Pixel Mask to something useful */
|
|
data->ramdac_wr(data->cookie, BT485_REG_PIXMASK, 0xff);
|
|
|
|
/*
|
|
* Initialize the RAMDAC info struct to hold all of our
|
|
* data, and fill it in.
|
|
*/
|
|
data->changed = DATA_ALL_CHANGED;
|
|
|
|
data->curenb = 0; /* cursor disabled */
|
|
data->curpos.x = data->curpos.y = 0; /* right now at 0,0 */
|
|
data->curhot.x = data->curhot.y = 0; /* hot spot at 0,0 */
|
|
|
|
/* initial cursor colormap: 0 is black, 1 is white */
|
|
data->curcmap_r[0] = data->curcmap_g[0] = data->curcmap_b[0] = 0;
|
|
data->curcmap_r[1] = data->curcmap_g[1] = data->curcmap_b[1] = 0xff;
|
|
|
|
/* initial cursor data: 64x64 block of white. */
|
|
data->cursize.x = data->cursize.y = 64;
|
|
for (i = 0; i < 512; i++)
|
|
data->curimage[i] = data->curmask[i] = 0xff;
|
|
|
|
/* Initial colormap: 0 is black, everything else is white */
|
|
data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0;
|
|
for (i = 1; i < 256; i++)
|
|
data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 255;
|
|
|
|
bt485_update((void *)data);
|
|
}
|
|
|
|
int
|
|
bt485_set_cmap(rc, cmapp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_cmap *cmapp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
u_int count, index;
|
|
uint8_t r[256], g[256], b[256];
|
|
int s, error;
|
|
|
|
if (cmapp->index >= 256 || cmapp->count > 256 - cmapp->index)
|
|
return (EINVAL);
|
|
|
|
index = cmapp->index;
|
|
count = cmapp->count;
|
|
error = copyin(cmapp->red, &r[index], count);
|
|
if (error)
|
|
return error;
|
|
error = copyin(cmapp->green, &g[index], count);
|
|
if (error)
|
|
return error;
|
|
error = copyin(cmapp->blue, &b[index], count);
|
|
if (error)
|
|
return error;
|
|
s = spltty();
|
|
memcpy(&data->cmap_r[index], &r[index], count);
|
|
memcpy(&data->cmap_g[index], &g[index], count);
|
|
memcpy(&data->cmap_b[index], &b[index], count);
|
|
data->changed |= DATA_CMAP_CHANGED;
|
|
data->ramdac_sched_update(data->cookie, bt485_update);
|
|
splx(s);
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
bt485_get_cmap(rc, cmapp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_cmap *cmapp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
u_int count, index;
|
|
int error;
|
|
|
|
if (cmapp->index >= 256 || cmapp->count > 256 - cmapp->index )
|
|
return (EINVAL);
|
|
|
|
count = cmapp->count;
|
|
index = cmapp->index;
|
|
error = copyout(&data->cmap_r[index], cmapp->red, count);
|
|
if (error)
|
|
return (error);
|
|
error = copyout(&data->cmap_g[index], cmapp->green, count);
|
|
if (error)
|
|
return (error);
|
|
error = copyout(&data->cmap_b[index], cmapp->blue, count);
|
|
return (error);
|
|
}
|
|
|
|
int
|
|
bt485_set_cursor(rc, cursorp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_cursor *cursorp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
u_int count = 0, icount = 0, index = 0, v;
|
|
char r[2], g[2], b[2], image[512], mask[512];
|
|
int s, error;
|
|
|
|
v = cursorp->which;
|
|
|
|
/*
|
|
* For DOCMAP and DOSHAPE, copy in the new data
|
|
* before we do anything that we can't recover from.
|
|
*/
|
|
if (v & WSDISPLAY_CURSOR_DOCMAP) {
|
|
if (cursorp->cmap.index > 2 ||
|
|
(cursorp->cmap.index + cursorp->cmap.count) > 2)
|
|
return (EINVAL);
|
|
count = cursorp->cmap.count;
|
|
index = cursorp->cmap.index;
|
|
error = copyin(cursorp->cmap.red, &r[index], count);
|
|
if (error)
|
|
return error;
|
|
error = copyin(cursorp->cmap.green, &g[index], count);
|
|
if (error)
|
|
return error;
|
|
error = copyin(cursorp->cmap.blue, &b[index], count);
|
|
if (error)
|
|
return error;
|
|
}
|
|
if (v & WSDISPLAY_CURSOR_DOSHAPE) {
|
|
if (cursorp->size.x > CURSOR_MAX_SIZE ||
|
|
cursorp->size.y > CURSOR_MAX_SIZE)
|
|
return (EINVAL);
|
|
icount = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
|
|
error = copyin(cursorp->image, image, icount);
|
|
if (error)
|
|
return error;
|
|
error = copyin(cursorp->mask, mask, icount);
|
|
if (error)
|
|
return error;
|
|
}
|
|
|
|
if (v & (WSDISPLAY_CURSOR_DOPOS | WSDISPLAY_CURSOR_DOCUR)) {
|
|
if (v & WSDISPLAY_CURSOR_DOPOS)
|
|
data->curpos = cursorp->pos;
|
|
if (v & WSDISPLAY_CURSOR_DOCUR)
|
|
data->curhot = cursorp->hot;
|
|
bt485_update_curpos(data);
|
|
}
|
|
|
|
s = spltty();
|
|
|
|
/* Data is all available; perform the requested operations. */
|
|
if (v & WSDISPLAY_CURSOR_DOCUR) {
|
|
data->curenb = cursorp->enable;
|
|
data->changed |= DATA_ENB_CHANGED;
|
|
}
|
|
if (v & WSDISPLAY_CURSOR_DOCMAP) {
|
|
memcpy(&data->curcmap_r[index], &r[index], count);
|
|
memcpy(&data->curcmap_g[index], &g[index], count);
|
|
memcpy(&data->curcmap_b[index], &b[index], count);
|
|
data->changed |= DATA_CURCMAP_CHANGED;
|
|
}
|
|
if (v & WSDISPLAY_CURSOR_DOSHAPE) {
|
|
data->cursize = cursorp->size;
|
|
count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
|
|
memset(data->curimage, 0, sizeof data->curimage);
|
|
memset(data->curmask, 0, sizeof data->curmask);
|
|
memcpy(data->curimage, image, icount);
|
|
memcpy(data->curmask, mask, icount);
|
|
data->changed |= DATA_CURSHAPE_CHANGED;
|
|
}
|
|
|
|
if (data->changed)
|
|
data->ramdac_sched_update(data->cookie, bt485_update);
|
|
splx(s);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
bt485_get_cursor(rc, cursorp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_cursor *cursorp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
int error, count;
|
|
|
|
/* we return everything they want */
|
|
cursorp->which = WSDISPLAY_CURSOR_DOALL;
|
|
|
|
cursorp->enable = data->curenb; /* DOCUR */
|
|
cursorp->pos = data->curpos; /* DOPOS */
|
|
cursorp->hot = data->curhot; /* DOHOT */
|
|
|
|
cursorp->cmap.index = 0; /* DOCMAP */
|
|
cursorp->cmap.count = 2;
|
|
if (cursorp->cmap.red != NULL) {
|
|
error = copyout(data->curcmap_r, cursorp->cmap.red, 2);
|
|
if (error)
|
|
return (error);
|
|
}
|
|
if (cursorp->cmap.green != NULL) {
|
|
error = copyout(data->curcmap_g, cursorp->cmap.green, 2);
|
|
if (error)
|
|
return (error);
|
|
}
|
|
if (cursorp->cmap.blue != NULL) {
|
|
error = copyout(data->curcmap_b, cursorp->cmap.blue, 2);
|
|
if (error)
|
|
return (error);
|
|
}
|
|
|
|
cursorp->size = data->cursize; /* DOSHAPE */
|
|
if (cursorp->image != NULL) {
|
|
count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
|
|
error = copyout(data->curimage, cursorp->image, count);
|
|
if (error)
|
|
return (error);
|
|
error = copyout(data->curmask, cursorp->mask, count);
|
|
if (error)
|
|
return (error);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
bt485_set_curpos(rc, curposp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_curpos *curposp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
|
|
data->curpos = *curposp;
|
|
bt485_update_curpos(data);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
bt485_get_curpos(rc, curposp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_curpos *curposp;
|
|
{
|
|
struct bt485data *data = (struct bt485data *)rc;
|
|
|
|
*curposp = data->curpos;
|
|
return (0);
|
|
}
|
|
|
|
int
|
|
bt485_get_curmax(rc, curposp)
|
|
struct ramdac_cookie *rc;
|
|
struct wsdisplay_curpos *curposp;
|
|
{
|
|
|
|
curposp->x = curposp->y = CURSOR_MAX_SIZE;
|
|
return (0);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
* Internal functions.
|
|
*/
|
|
|
|
inline void
|
|
bt485_wr_i(data, ireg, val)
|
|
struct bt485data *data;
|
|
u_int8_t ireg;
|
|
u_int8_t val;
|
|
{
|
|
data->ramdac_wr(data->cookie, BT485_REG_PCRAM_WRADDR, ireg);
|
|
data->ramdac_wr(data->cookie, BT485_REG_EXTENDED, val);
|
|
}
|
|
|
|
inline u_int8_t
|
|
bt485_rd_i(data, ireg)
|
|
struct bt485data *data;
|
|
u_int8_t ireg;
|
|
{
|
|
data->ramdac_wr(data->cookie, BT485_REG_PCRAM_WRADDR, ireg);
|
|
return (data->ramdac_rd(data->cookie, BT485_REG_EXTENDED));
|
|
}
|
|
|
|
void
|
|
bt485_update(vp)
|
|
void *vp;
|
|
{
|
|
struct bt485data *data = vp;
|
|
u_int8_t regval;
|
|
int count, i, v;
|
|
|
|
v = data->changed;
|
|
data->changed = 0;
|
|
|
|
if (v & DATA_ENB_CHANGED) {
|
|
regval = data->ramdac_rd(data->cookie, BT485_REG_COMMAND_2);
|
|
if (data->curenb)
|
|
regval |= 0x01;
|
|
else
|
|
regval &= ~0x03;
|
|
data->ramdac_wr(data->cookie, BT485_REG_COMMAND_2, regval);
|
|
}
|
|
|
|
if (v & DATA_CURCMAP_CHANGED) {
|
|
/* addr[9:0] assumed to be 0 */
|
|
/* set addr[7:0] to 1 */
|
|
data->ramdac_wr(data->cookie, BT485_REG_COC_WRADDR, 0x01);
|
|
|
|
/* spit out the cursor data */
|
|
for (i = 0; i < 2; i++) {
|
|
data->ramdac_wr(data->cookie, BT485_REG_COCDATA,
|
|
data->curcmap_r[i]);
|
|
data->ramdac_wr(data->cookie, BT485_REG_COCDATA,
|
|
data->curcmap_g[i]);
|
|
data->ramdac_wr(data->cookie, BT485_REG_COCDATA,
|
|
data->curcmap_b[i]);
|
|
}
|
|
}
|
|
|
|
if (v & DATA_CURSHAPE_CHANGED) {
|
|
count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y;
|
|
|
|
/*
|
|
* Write the cursor image data:
|
|
* set addr[9:8] to 0,
|
|
* set addr[7:0] to 0,
|
|
* spit it all out.
|
|
*/
|
|
regval = bt485_rd_i(data, BT485_IREG_COMMAND_3);
|
|
regval &= ~0x03;
|
|
bt485_wr_i(data, BT485_IREG_COMMAND_3, regval);
|
|
data->ramdac_wr(data->cookie, BT485_REG_PCRAM_WRADDR, 0);
|
|
for (i = 0; i < count; i++)
|
|
data->ramdac_wr(data->cookie, BT485_REG_CURSOR_RAM,
|
|
data->curimage[i]);
|
|
|
|
/*
|
|
* Write the cursor mask data:
|
|
* set addr[9:8] to 2,
|
|
* set addr[7:0] to 0,
|
|
* spit it all out.
|
|
*/
|
|
regval = bt485_rd_i(data, BT485_IREG_COMMAND_3);
|
|
regval &= ~0x03; regval |= 0x02;
|
|
bt485_wr_i(data, BT485_IREG_COMMAND_3, regval);
|
|
data->ramdac_wr(data->cookie, BT485_REG_PCRAM_WRADDR, 0);
|
|
for (i = 0; i < count; i++)
|
|
data->ramdac_wr(data->cookie, BT485_REG_CURSOR_RAM,
|
|
data->curmask[i]);
|
|
|
|
/* set addr[9:0] back to 0 */
|
|
regval = bt485_rd_i(data, BT485_IREG_COMMAND_3);
|
|
regval &= ~0x03;
|
|
bt485_wr_i(data, BT485_IREG_COMMAND_3, regval);
|
|
}
|
|
|
|
if (v & DATA_CMAP_CHANGED) {
|
|
/* addr[9:0] assumed to be 0 */
|
|
/* set addr[7:0] to 0 */
|
|
data->ramdac_wr(data->cookie, BT485_REG_PCRAM_WRADDR, 0x00);
|
|
|
|
/* spit out the cursor data */
|
|
for (i = 0; i < 256; i++) {
|
|
data->ramdac_wr(data->cookie, BT485_REG_PALETTE,
|
|
data->cmap_r[i]);
|
|
data->ramdac_wr(data->cookie, BT485_REG_PALETTE,
|
|
data->cmap_g[i]);
|
|
data->ramdac_wr(data->cookie, BT485_REG_PALETTE,
|
|
data->cmap_b[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
bt485_update_curpos(data)
|
|
struct bt485data *data;
|
|
{
|
|
void *cookie = data->cookie;
|
|
int s, x, y;
|
|
|
|
s = spltty();
|
|
|
|
x = data->curpos.x + CURSOR_MAX_SIZE - data->curhot.x;
|
|
y = data->curpos.y + CURSOR_MAX_SIZE - data->curhot.y;
|
|
data->ramdac_wr(cookie, BT485_REG_CURSOR_X_LOW, x & 0xff);
|
|
data->ramdac_wr(cookie, BT485_REG_CURSOR_X_HIGH, (x >> 8) & 0x0f);
|
|
data->ramdac_wr(cookie, BT485_REG_CURSOR_Y_LOW, y & 0xff);
|
|
data->ramdac_wr(cookie, BT485_REG_CURSOR_Y_HIGH, (y >> 8) & 0x0f);
|
|
|
|
splx(s);
|
|
}
|