Change pmax framebuffer drivers to use Ted Lemon's port of the
NetBSD/sparc rcons glass-tty console pseudo-device driver, via the "fb" generic-framebuffer pseudo-device driver. Individual framebuffer device drivers are now autoconfig glue, and initialization code for a set of vdac/ramdac-level methods, called "fbdriver", that's used by all the pmax device drivers. All the handlers for user-level requests (open/ioctl/read/write/close) are moved into the fb pseudo-device driver, which uses the the "fbdriver" methods to work on any given pmax hardware driver. Framebuffers supported are: sfb cfb mfb xcfb pm. Move the qvss (pm) -style mmap()ed device interface, kernel tracking of mouse button/movement events, and placing mouse/keyboard events in an mmap()ed ring buffer, out of the framebuffer device drivers and into separate source files. The fb pseudo-device driver uses the qvss-compatible interface, since that's what the (R5) X server uses.
This commit is contained in:
parent
ef09db9674
commit
1d976e39b9
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,204 @@
|
|||
/*ARGSUSED*/
|
||||
fbopen(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct fbinfo *fi;
|
||||
int s;
|
||||
|
||||
#ifdef fpinitialized
|
||||
if (!fp->initialized)
|
||||
return (ENXIO);
|
||||
#endif
|
||||
|
||||
if (minor(dev) >= fbcd.cd_ndevs ||
|
||||
(fi = fbcd.cd_devs[minor(dev)]) == NULL)
|
||||
return(ENXIO);
|
||||
|
||||
if (fi->fi_open)
|
||||
return (EBUSY);
|
||||
|
||||
fi->fi_open = 1;
|
||||
|
||||
(*fi->fi_driver->fbd_initcmap)(fi);
|
||||
|
||||
/*
|
||||
* Set up event queue for later
|
||||
*/
|
||||
pmEventQueueInit(&fi->fi_fbu->scrInfo.qe);
|
||||
genConfigMouse();
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
fbclose(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct fbinfo *fi;
|
||||
register struct pmax_fbtty *fbtty;
|
||||
int pixelsize;
|
||||
int s;
|
||||
|
||||
if (minor(dev) >= fbcd.cd_ndevs ||
|
||||
(fi = fbcd.cd_devs[minor(dev)]) == NULL)
|
||||
return(EBADF);
|
||||
|
||||
if (!fi->fi_open)
|
||||
return (EBADF);
|
||||
|
||||
fbtty = fi->fi_glasstty;
|
||||
fi->fi_open = 0;
|
||||
(*fi->fi_driver->fbd_initcmap)(fi);
|
||||
genDeconfigMouse();
|
||||
fbScreenInit(fi);
|
||||
|
||||
bzero((caddr_t)fi->fi_pixels, fi->fi_pixelsize);
|
||||
(*fi->fi_driver->fbd_poscursor)
|
||||
(fi, fbtty->col * 8, fbtty->row * 15);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
fbioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
caddr_t data;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct fbinfo *fi;
|
||||
register struct pmax_fbtty *fbtty;
|
||||
int s;
|
||||
|
||||
if (minor(dev) >= fbcd.cd_ndevs ||
|
||||
(fi = fbcd.cd_devs[minor(dev)]) == NULL)
|
||||
return(EBADF);
|
||||
|
||||
fbtty = fi->fi_glasstty;
|
||||
|
||||
switch (cmd) {
|
||||
case QIOCGINFO:
|
||||
return (fbmmap_fb(fi, dev, data, p));
|
||||
|
||||
case QIOCPMSTATE:
|
||||
/*
|
||||
* Set mouse state.
|
||||
*/
|
||||
fi->fi_fbu->scrInfo.mouse = *(pmCursor *)data;
|
||||
(*fi->fi_driver->fbd_poscursor)
|
||||
(fi, fi->fi_fbu->scrInfo.mouse.x,
|
||||
fi->fi_fbu->scrInfo.mouse.y);
|
||||
break;
|
||||
|
||||
case QIOCINIT:
|
||||
/*
|
||||
* Initialize the screen.
|
||||
*/
|
||||
fbScreenInit(fi);
|
||||
break;
|
||||
|
||||
case QIOCKPCMD:
|
||||
{
|
||||
pmKpCmd *kpCmdPtr;
|
||||
unsigned char *cp;
|
||||
|
||||
kpCmdPtr = (pmKpCmd *)data;
|
||||
if (kpCmdPtr->nbytes == 0)
|
||||
kpCmdPtr->cmd |= 0x80;
|
||||
if (!fi->fi_open)
|
||||
kpCmdPtr->cmd |= 1;
|
||||
(*fbtty->KBDPutc)(fbtty->kbddev, (int)kpCmdPtr->cmd);
|
||||
cp = &kpCmdPtr->par[0];
|
||||
for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
|
||||
if (kpCmdPtr->nbytes == 1)
|
||||
*cp |= 0x80;
|
||||
(*fbtty->KBDPutc)(fbtty->kbddev, (int)*cp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case QIOCADDR:
|
||||
*(PM_Info **)data = &fi->fi_fbu->scrInfo;
|
||||
break;
|
||||
|
||||
case QIOWCURSOR:
|
||||
(*fi->fi_driver->fbd_loadcursor)
|
||||
(fi, (unsigned short *)data);
|
||||
break;
|
||||
|
||||
case QIOWCURSORCOLOR:
|
||||
(*fi->fi_driver->fbd_cursorcolor)(fi, (unsigned int *)data);
|
||||
break;
|
||||
|
||||
case QIOSETCMAP:
|
||||
(*fi->fi_driver->fbd_putcmap)
|
||||
(fi,
|
||||
(char *)&((ColorMap *)data)->Entry,
|
||||
((ColorMap *)data)->index, 1);
|
||||
break;
|
||||
|
||||
case QIOKERNLOOP:
|
||||
genConfigMouse();
|
||||
break;
|
||||
|
||||
case QIOKERNUNLOOP:
|
||||
genDeconfigMouse();
|
||||
break;
|
||||
|
||||
case QIOVIDEOON:
|
||||
(*fi->fi_driver->fbd_unblank) (fi);
|
||||
break;
|
||||
|
||||
case QIOVIDEOOFF:
|
||||
(*fi->fi_driver->fbd_blank) (fi);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("fb%d: Unknown ioctl command %x\n", minor(dev), cmd);
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
fbselect(dev, flag, p)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct fbinfo *fi = fbcd.cd_devs[minor(dev)];
|
||||
|
||||
switch (flag) {
|
||||
case FREAD:
|
||||
if (fi->fi_fbu->scrInfo.qe.eHead !=
|
||||
fi->fi_fbu->scrInfo.qe.eTail)
|
||||
return (1);
|
||||
selrecord(p, &fi->fi_selp);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the physical page number that corresponds to byte offset 'off'.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
fbmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
{
|
||||
int len;
|
||||
register struct fbinfo *fi;
|
||||
|
||||
if (minor(dev) >= fbcd.cd_ndevs ||
|
||||
(fi = fbcd.cd_devs[minor(dev)]) == NULL)
|
||||
return(-1);
|
||||
|
||||
len = pmax_round_page(((vm_offset_t)fi->fi_fbu & PGOFSET)
|
||||
+ sizeof(*fi->fi_fbu));
|
||||
if (off < len)
|
||||
return pmax_btop(MACH_CACHED_TO_PHYS(fi->fi_fbu) + off);
|
||||
off -= len;
|
||||
if (off >= fi->fi_type.fb_size)
|
||||
return (-1);
|
||||
return pmax_btop(MACH_UNCACHED_TO_PHYS(fi->fi_pixels) + off);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pm.c,v 1.6 1995/08/10 04:21:44 jonathan Exp $ */
|
||||
/* $NetBSD: pm.c,v 1.7 1995/09/11 07:45:43 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -56,6 +56,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <fb.h>
|
||||
#include <pm.h>
|
||||
#include <dc.h>
|
||||
#if NPM > 0
|
||||
|
@ -81,42 +82,77 @@ pm needs dc device
|
|||
#include <machine/dc7085cons.h>
|
||||
#include <machine/pmioctl.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/fbvar.h>
|
||||
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/cons.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/pmreg.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <pmax/dev/pmreg.h>
|
||||
#include <pmax/dev/bt478.h>
|
||||
|
||||
/*
|
||||
* These need to be mapped into user space.
|
||||
*/
|
||||
struct fbuaccess pmu;
|
||||
struct pmax_fb pmfb;
|
||||
static u_short curReg; /* copy of PCCRegs.cmdr since it's read only */
|
||||
|
||||
/*
|
||||
* rcons methods and globals.
|
||||
*/
|
||||
struct pmax_fbtty pmfb;
|
||||
struct fbinfo pmfi; /*XXX*/
|
||||
|
||||
/*
|
||||
* Forward references.
|
||||
*/
|
||||
static void pmScreenInit __P(());
|
||||
static void pmLoadCursor __P((u_short *ptr));
|
||||
extern void pmScreenInit __P((struct fbinfo *fi));
|
||||
static void pmLoadCursor __P((struct fbinfo *fi, u_short *ptr));
|
||||
void pmPosCursor __P((struct fbinfo *fi, int x, int y));
|
||||
|
||||
#ifdef notyet /* these should be removed */
|
||||
static void pmRestoreCursorColor __P(());
|
||||
static void pmCursorColor __P((u_int *color));
|
||||
void pmPosCursor __P((int x, int y));
|
||||
static void pmInitColorMap __P(());
|
||||
static void pmLoadColorMap __P ((ColorMap *ptr));
|
||||
|
||||
#endif
|
||||
void bt478CursorColor __P((struct fbinfo *fi, u_int *color));
|
||||
void bt478InitColorMap __P((struct fbinfo *fi));
|
||||
|
||||
static void pmLoadColorMap __P ((ColorMap *ptr)); /*XXX*/
|
||||
|
||||
|
||||
int pminit __P((struct fbinfo *fi, int unit, int silent));
|
||||
|
||||
static int pm_video_on __P ((struct fbinfo *));
|
||||
static int pm_video_off __P ((struct fbinfo *));
|
||||
int bt478LoadColorMap __P ((struct fbinfo *, caddr_t, int, int));
|
||||
int bt478GetColorMap __P ((struct fbinfo *, caddr_t, int, int));
|
||||
|
||||
|
||||
#if 0
|
||||
static void pmVDACInit();
|
||||
|
||||
void pmKbdEvent(), pmMouseEvent(), pmMouseButtons();
|
||||
#endif
|
||||
|
||||
/* pm framebuffers are only found in {dec,vax}station 3100s with dc7085s */
|
||||
|
||||
extern void dcPutc();
|
||||
extern void (*dcDivertXInput)();
|
||||
extern void (*dcMouseEvent)();
|
||||
extern void (*dcMouseButtons)();
|
||||
extern int pmax_boardtype;
|
||||
extern u_short defCursor[32];
|
||||
extern struct consdev cn_tab;
|
||||
|
||||
void genConfigMouse(), genDeconfigMouse();
|
||||
void genKbdEvent(), genMouseEvent(), genMouseButtons();
|
||||
|
||||
extern void pmEventQueueInit __P((pmEventQueue *qe));
|
||||
|
||||
#define CMAP_BITS (3 * 256) /* 256 entries, 3 bytes per. */
|
||||
static u_char cmap_bits [NPM * CMAP_BITS]; /* One colormap per pm... */
|
||||
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.new.
|
||||
|
@ -131,6 +167,19 @@ struct cfdriver pmcd = {
|
|||
NULL, "pm", pmmatch, pmattach, DV_DULL, sizeof(struct device), 0
|
||||
};
|
||||
|
||||
/* new-style raster-cons "driver" methods */
|
||||
|
||||
struct fbdriver pm_driver = {
|
||||
pm_video_on,
|
||||
pm_video_off,
|
||||
bt478InitColorMap,
|
||||
bt478GetColorMap,
|
||||
bt478LoadColorMap,
|
||||
pmPosCursor,
|
||||
pmLoadCursor,
|
||||
bt478CursorColor,
|
||||
};
|
||||
|
||||
int
|
||||
pmmatch(parent, match, aux)
|
||||
struct device *parent;
|
||||
|
@ -140,11 +189,16 @@ pmmatch(parent, match, aux)
|
|||
struct cfdata *cf = match;
|
||||
struct confargs *ca = aux;
|
||||
static int npms = 1;
|
||||
caddr_t pmaddr = BUS_CVTADDR(ca);
|
||||
|
||||
|
||||
/* make sure that we're looking for this type of device. */
|
||||
if (!BUS_MATCHNAME(ca, "pm"))
|
||||
return (0);
|
||||
|
||||
if (badaddr(pmaddr, 4))
|
||||
return (0);
|
||||
|
||||
#ifdef notyet
|
||||
/* if it can't have the one mentioned, reject it */
|
||||
if (cf->cf_unit >= npms)
|
||||
|
@ -160,8 +214,9 @@ pmattach(parent, self, aux)
|
|||
void *aux;
|
||||
{
|
||||
struct confargs *ca = aux;
|
||||
caddr_t pmaddr = BUS_CVTADDR(ca);
|
||||
|
||||
if (!pminit(BUS_CVTADDR(ca)))
|
||||
if (!pminit(&pmfi, 0, 0))
|
||||
return;
|
||||
|
||||
/* no interrupts for PM */
|
||||
|
@ -169,232 +224,73 @@ pmattach(parent, self, aux)
|
|||
return;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
pmopen(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
int s;
|
||||
|
||||
if (!fp->initialized)
|
||||
return (ENXIO);
|
||||
if (fp->GraphicsOpen)
|
||||
return (EBUSY);
|
||||
|
||||
fp->GraphicsOpen = 1;
|
||||
if (!fp->isMono)
|
||||
pmInitColorMap();
|
||||
/*
|
||||
* 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);
|
||||
s = spltty();
|
||||
dcDivertXInput = pmKbdEvent;
|
||||
dcMouseEvent = pmMouseEvent;
|
||||
dcMouseButtons = pmMouseButtons;
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
pmclose(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
int s;
|
||||
|
||||
if (!fp->GraphicsOpen)
|
||||
return (EBADF);
|
||||
|
||||
fp->GraphicsOpen = 0;
|
||||
if (!fp->isMono)
|
||||
pmInitColorMap();
|
||||
s = spltty();
|
||||
dcDivertXInput = (void (*)())0;
|
||||
dcMouseEvent = (void (*)())0;
|
||||
dcMouseButtons = (void (*)())0;
|
||||
splx(s);
|
||||
pmScreenInit();
|
||||
bzero((caddr_t)fp->fr_addr,
|
||||
(fp->isMono ? 1024 / 8 : 1024) * 864);
|
||||
pmPosCursor(fp->col * 8, fp->row * 15);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
pmioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
caddr_t data;
|
||||
struct proc *p;
|
||||
{
|
||||
register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
int s;
|
||||
|
||||
switch (cmd) {
|
||||
case QIOCGINFO:
|
||||
return (fbmmap(fp, dev, data, p));
|
||||
|
||||
case QIOCPMSTATE:
|
||||
/*
|
||||
* Set mouse state.
|
||||
*/
|
||||
fp->fbu->scrInfo.mouse = *(pmCursor *)data;
|
||||
pmPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
|
||||
break;
|
||||
|
||||
case QIOCINIT:
|
||||
/*
|
||||
* Initialize the screen.
|
||||
*/
|
||||
pmScreenInit();
|
||||
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:
|
||||
pmLoadCursor((unsigned short *)data);
|
||||
break;
|
||||
|
||||
case QIOWCURSORCOLOR:
|
||||
pmCursorColor((unsigned int *)data);
|
||||
break;
|
||||
|
||||
case QIOSETCMAP:
|
||||
pmLoadColorMap((ColorMap *)data);
|
||||
break;
|
||||
|
||||
case QIOKERNLOOP:
|
||||
s = spltty();
|
||||
dcDivertXInput = pmKbdEvent;
|
||||
dcMouseEvent = pmMouseEvent;
|
||||
dcMouseButtons = pmMouseButtons;
|
||||
splx(s);
|
||||
break;
|
||||
|
||||
case QIOKERNUNLOOP:
|
||||
s = spltty();
|
||||
dcDivertXInput = (void (*)())0;
|
||||
dcMouseEvent = (void (*)())0;
|
||||
dcMouseButtons = (void (*)())0;
|
||||
splx(s);
|
||||
break;
|
||||
|
||||
case QIOVIDEOON:
|
||||
if (!fp->isMono)
|
||||
pmRestoreCursorColor();
|
||||
curReg |= PCC_ENPA;
|
||||
curReg &= ~PCC_FOPB;
|
||||
pcc->cmdr = curReg;
|
||||
break;
|
||||
|
||||
case QIOVIDEOOFF:
|
||||
if (!fp->isMono)
|
||||
pmVDACInit();
|
||||
curReg |= PCC_FOPB;
|
||||
curReg &= ~PCC_ENPA;
|
||||
pcc->cmdr = curReg;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("pm0: Unknown ioctl command %x\n", cmd);
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the physical page number that corresponds to byte offset 'off'.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
pmmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
{
|
||||
int len;
|
||||
|
||||
len = pmax_round_page(((vm_offset_t)&pmu & PGOFSET) + sizeof(pmu));
|
||||
if (off < len)
|
||||
return pmax_btop(MACH_CACHED_TO_PHYS(&pmu) + off);
|
||||
off -= len;
|
||||
if (off >= pmfb.fr_size)
|
||||
return (-1);
|
||||
return pmax_btop(MACH_UNCACHED_TO_PHYS(pmfb.fr_addr) + off);
|
||||
}
|
||||
|
||||
pmselect(dev, flag, p)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct pmax_fb *fp = &pmfb;
|
||||
|
||||
switch (flag) {
|
||||
case FREAD:
|
||||
if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
|
||||
return (1);
|
||||
selrecord(p, &fp->selp);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static u_char bg_RGB[3]; /* background color for the cursor */
|
||||
static u_char fg_RGB[3]; /* foreground color for the cursor */
|
||||
|
||||
/*
|
||||
* Test to see if device is present.
|
||||
* Return true if found and initialized ok.
|
||||
*/
|
||||
pminit()
|
||||
pminit(fi, unit, silent)
|
||||
struct fbinfo *fi;
|
||||
int unit;
|
||||
int silent;
|
||||
{
|
||||
register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
|
||||
fp->isMono = *(volatile u_short *)MACH_PHYS_TO_UNCACHED(KN01_SYS_CSR) &
|
||||
KN01_CSR_MONO;
|
||||
fp->fr_addr = (char *)MACH_PHYS_TO_UNCACHED(KN01_PHYS_FBUF_START);
|
||||
fp->fr_size = fp->isMono ? 0x40000 : 0x100000;
|
||||
/* Set address of frame buffer... */
|
||||
fi->fi_pixels = (caddr_t)MACH_PHYS_TO_UNCACHED(KN01_PHYS_FBUF_START);
|
||||
|
||||
/* Fill in the stuff that differs from monochrome to color. */
|
||||
if (*(volatile u_short *)MACH_PHYS_TO_UNCACHED(KN01_SYS_CSR) &
|
||||
KN01_CSR_MONO) {
|
||||
/* check for no frame buffer */
|
||||
if (badaddr((char *)fi->fi_pixels, 4))
|
||||
return (0);
|
||||
|
||||
fi->fi_type.fb_depth = 1;
|
||||
fi->fi_type.fb_cmsize = 0;
|
||||
fi->fi_type.fb_boardtype = PMAX_FBTYPE_PM_MONO;
|
||||
fi->fi_type.fb_size = 0x40000;
|
||||
fi->fi_linebytes = 256;
|
||||
} else {
|
||||
fi->fi_type.fb_depth = 8;
|
||||
fi->fi_type.fb_cmsize = 256;
|
||||
fi->fi_type.fb_boardtype = PMAX_FBTYPE_PM_COLOR;
|
||||
fi->fi_type.fb_size = 0x100000;
|
||||
fi->fi_linebytes = 1024;
|
||||
}
|
||||
|
||||
/* Fill in main frame buffer info struct. */
|
||||
|
||||
fi->fi_pixelsize =
|
||||
((fi->fi_type.fb_depth == 1) ? 1024 / 8 : 1024) * 864;
|
||||
fi->fi_unit = unit;
|
||||
fi->fi_base = (caddr_t)pcc;
|
||||
fi->fi_vdac = (caddr_t)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
|
||||
fi->fi_blanked = 0;
|
||||
fi->fi_cmap_bits = (caddr_t)&cmap_bits [CMAP_BITS * unit];
|
||||
|
||||
fi->fi_type.fb_width = 1024;
|
||||
fi->fi_type.fb_height = 864;
|
||||
|
||||
|
||||
/*
|
||||
* compatibility glue
|
||||
*/
|
||||
fi->fi_glasstty = &pmfb;
|
||||
|
||||
|
||||
/*
|
||||
* Must be in Uncached space since the fbuaccess structure is
|
||||
* mapped into the user's address space uncached.
|
||||
*/
|
||||
fp->fbu = (struct fbuaccess *)
|
||||
fi->fi_fbu = (struct fbuaccess *)
|
||||
MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&pmu));
|
||||
fp->posCursor = pmPosCursor;
|
||||
fp->KBDPutc = dcPutc;
|
||||
fp->kbddev = makedev(DCDEV, DCKBD_PORT);
|
||||
if (fp->isMono) {
|
||||
fi->fi_glasstty->KBDPutc = dcPutc;
|
||||
fi->fi_glasstty->kbddev = makedev(DCDEV, DCKBD_PORT);
|
||||
|
||||
if (fi->fi_type.fb_depth == 1) {
|
||||
/* check for no frame buffer */
|
||||
if (badaddr((char *)fp->fr_addr, 4))
|
||||
if (badaddr((char *)fi->fi_pixels, 4))
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -408,74 +304,47 @@ pminit()
|
|||
*/
|
||||
pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB;
|
||||
|
||||
/*
|
||||
* Initialize screen info.
|
||||
*/
|
||||
fp->fbu->scrInfo.max_row = 56;
|
||||
fp->fbu->scrInfo.max_col = 80;
|
||||
fp->fbu->scrInfo.max_x = 1024;
|
||||
fp->fbu->scrInfo.max_y = 864;
|
||||
fp->fbu->scrInfo.max_cur_x = 1023;
|
||||
fp->fbu->scrInfo.max_cur_y = 863;
|
||||
fp->fbu->scrInfo.version = 11;
|
||||
fp->fbu->scrInfo.mthreshold = 4;
|
||||
fp->fbu->scrInfo.mscale = 2;
|
||||
fp->fbu->scrInfo.min_cur_x = -15;
|
||||
fp->fbu->scrInfo.min_cur_y = -15;
|
||||
fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
|
||||
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;
|
||||
|
||||
/*
|
||||
* Initialize the color map, the screen, and the mouse.
|
||||
*/
|
||||
pmInitColorMap();
|
||||
pmScreenInit();
|
||||
fbScroll(fp);
|
||||
bt478init(&pmfi);
|
||||
|
||||
/*
|
||||
* Initialize old-style pmax screen info.
|
||||
*/
|
||||
fi->fi_fbu->scrInfo.max_row = 56;
|
||||
fi->fi_fbu->scrInfo.max_col = 80;
|
||||
|
||||
init_pmaxfbu(fi);
|
||||
|
||||
/* These are non-zero on the kn01 framebuffer. Why? */
|
||||
fi->fi_fbu->scrInfo.min_cur_x = -15;
|
||||
fi->fi_fbu->scrInfo.min_cur_y = -15;
|
||||
|
||||
|
||||
#ifdef notanymore
|
||||
bt478InitColorMap(&pmfi); /* done inside bt478init() */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Connect to the raster-console pseudo-driver.
|
||||
*/
|
||||
fi->fi_glasstty = &pmfb; /*XXX*/
|
||||
fbconnect((fi->fi_type.fb_depth == 1) ? "KN01 mfb" : "KN01 cfb",
|
||||
fi, silent);
|
||||
|
||||
|
||||
#ifdef fpinitialized
|
||||
fp->initialized = 1;
|
||||
if (cn_tab.cn_fb == (struct pmax_fb *)0)
|
||||
cn_tab.cn_fb = fp;
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* pmScreenInit --
|
||||
*
|
||||
* Initialize the screen.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The screen is initialized.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
pmScreenInit()
|
||||
{
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
|
||||
/*
|
||||
* Home the cursor.
|
||||
* We want an LSI terminal emulation. We want the graphics
|
||||
* terminal to scroll from the bottom. So start at the bottom.
|
||||
*/
|
||||
fp->row = 55;
|
||||
fp->col = 0;
|
||||
|
||||
/*
|
||||
* Load the cursor with the default values
|
||||
*
|
||||
*/
|
||||
pmLoadCursor(defCursor);
|
||||
}
|
||||
|
||||
|
||||
static u_char bg_RGB[3]; /* background color for the cursor */
|
||||
static u_char fg_RGB[3]; /* foreground color for the cursor */
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
@ -492,7 +361,8 @@ pmScreenInit()
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
pmLoadCursor(cur)
|
||||
pmLoadCursor(fi, cur)
|
||||
struct fbinfo *fi;
|
||||
unsigned short *cur;
|
||||
{
|
||||
register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
|
||||
|
@ -508,6 +378,7 @@ pmLoadCursor(cur)
|
|||
pcc->cmdr = curReg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
@ -524,7 +395,8 @@ pmLoadCursor(cur)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
pmRestoreCursorColor()
|
||||
pmRestoreCursorColor(fi)
|
||||
struct fbinfo *fi;
|
||||
{
|
||||
register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
|
||||
register int i;
|
||||
|
@ -603,13 +475,12 @@ static void
|
|||
pmInitColorMap()
|
||||
{
|
||||
register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
|
||||
struct pmax_fb *fp = &pmfb;
|
||||
register int i;
|
||||
|
||||
*(volatile char *)MACH_PHYS_TO_UNCACHED(KN01_PHYS_COLMASK_START) = 0xff;
|
||||
MachEmptyWriteBuffer();
|
||||
|
||||
if (fp->isMono) {
|
||||
if (fi->fi_type.fb_depth == 1) {
|
||||
vdac->mapWA = 0; MachEmptyWriteBuffer();
|
||||
for (i = 0; i < 256; i++) {
|
||||
vdac->map = (i < 128) ? 0x00 : 0xff;
|
||||
|
@ -639,43 +510,10 @@ pmInitColorMap()
|
|||
pmRestoreCursorColor();
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* pmVDACInit --
|
||||
*
|
||||
* Initialize the VDAC.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
pmVDACInit()
|
||||
{
|
||||
register VDACRegs *vdac = (VDACRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_VDAC);
|
||||
|
||||
/*
|
||||
*
|
||||
* Initialize the VDAC
|
||||
*/
|
||||
vdac->overWA = 0x04; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x00; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x00; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x00; MachEmptyWriteBuffer();
|
||||
vdac->overWA = 0x08; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x00; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x00; MachEmptyWriteBuffer();
|
||||
vdac->over = 0x7f; MachEmptyWriteBuffer();
|
||||
vdac->overWA = 0x0c; MachEmptyWriteBuffer();
|
||||
vdac->over = 0xff; MachEmptyWriteBuffer();
|
||||
vdac->over = 0xff; MachEmptyWriteBuffer();
|
||||
vdac->over = 0xff; MachEmptyWriteBuffer();
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/* should zap pmloadcolormap too, but i haven't fixed the callers yet */
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
@ -707,6 +545,8 @@ pmLoadColorMap(ptr)
|
|||
vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
@ -723,44 +563,55 @@ pmLoadColorMap(ptr)
|
|||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
pmPosCursor(x, y)
|
||||
pmPosCursor(fi, x, y)
|
||||
register struct fbinfo *fi;
|
||||
register int x, y;
|
||||
{
|
||||
register PCCRegs *pcc = (PCCRegs *)MACH_PHYS_TO_UNCACHED(KN01_SYS_PCC);
|
||||
register struct pmax_fb *fp = &pmfb;
|
||||
|
||||
if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
|
||||
y = fp->fbu->scrInfo.max_cur_y;
|
||||
if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
|
||||
x = fp->fbu->scrInfo.max_cur_x;
|
||||
fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
|
||||
fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
|
||||
if (y < fi->fi_fbu->scrInfo.min_cur_y ||
|
||||
y > fi->fi_fbu->scrInfo.max_cur_y)
|
||||
y = fi->fi_fbu->scrInfo.max_cur_y;
|
||||
if (x < fi->fi_fbu->scrInfo.min_cur_x ||
|
||||
x > fi->fi_fbu->scrInfo.max_cur_x)
|
||||
x = fi->fi_fbu->scrInfo.max_cur_x;
|
||||
fi->fi_fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
|
||||
fi->fi_fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
|
||||
pcc->xpos = PCC_X_OFFSET + x;
|
||||
pcc->ypos = PCC_Y_OFFSET + y;
|
||||
}
|
||||
|
||||
/*
|
||||
* pm keyboard and mouse input. Just punt to the generic ones in fb.c
|
||||
*/
|
||||
void
|
||||
pmKbdEvent(ch)
|
||||
int ch;
|
||||
/* enable the video display. */
|
||||
|
||||
static int pm_video_on (fi)
|
||||
struct fbinfo *fi;
|
||||
{
|
||||
fbKbdEvent(ch, &pmfb);
|
||||
register PCCRegs *pcc = (PCCRegs *)fi -> fi_base;
|
||||
|
||||
if (!fi -> fi_blanked)
|
||||
return 0;
|
||||
|
||||
pcc -> cmdr = curReg & ~(PCC_FOPA | PCC_FOPB);
|
||||
bt478RestoreCursorColor (fi);
|
||||
fi -> fi_blanked = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pmMouseEvent(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
/* disable the video display. */
|
||||
|
||||
static int pm_video_off (fi)
|
||||
struct fbinfo *fi;
|
||||
{
|
||||
fbMouseEvent(newRepPtr, &pmfb);
|
||||
register PCCRegs *pcc = (PCCRegs *)fi -> fi_base;
|
||||
|
||||
if (fi -> fi_blanked)
|
||||
return 0;
|
||||
|
||||
bt478BlankCursor (fi);
|
||||
pcc -> cmdr = curReg | PCC_FOPA | PCC_FOPB;
|
||||
fi -> fi_blanked = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pmMouseButtons(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
{
|
||||
fbMouseButtons(newRepPtr, &pmfb);
|
||||
}
|
||||
#endif /* NDC */
|
||||
#endif /* NPM */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: promio.c,v 1.1 1995/04/11 10:08:42 mellon Exp $ */
|
||||
/* $NetBSD: promio.c,v 1.2 1995/09/11 07:45:50 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,6 +43,8 @@
|
|||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <dev/cons.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
|
@ -53,7 +55,6 @@
|
|||
|
||||
#include <pmax/stand/dec_prom.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/sccreg.h>
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
|
@ -63,18 +64,20 @@
|
|||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/turbochannel.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
/* #include <pmax/pmax/cons.h> */
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/machConst.h>
|
||||
#include <machine/pmioctl.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <machine/fbio.h>
|
||||
#include <sparc/rcons/raster.h>
|
||||
#include <machine/fbvar.h>
|
||||
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <pmax/tc/tc.h>
|
||||
|
||||
|
||||
#include <pm.h>
|
||||
#include <cfb.h>
|
||||
#include <mfb.h>
|
||||
|
@ -87,6 +90,7 @@
|
|||
#include <asc.h>
|
||||
|
||||
#if NDC > 0
|
||||
#include <machine/dc7085cons.h>
|
||||
extern int dcGetc(), dcparam();
|
||||
extern void dcPutc();
|
||||
#endif
|
||||
|
@ -101,6 +105,8 @@ static int romgetc __P ((dev_t));
|
|||
static void romputc __P ((dev_t, int));
|
||||
static void rompollc __P((dev_t, int));
|
||||
|
||||
extern int LKgetc __P((dev_t dev)); /* should be in header file, but which one? */
|
||||
|
||||
int pmax_boardtype; /* Mother board type */
|
||||
|
||||
/*
|
||||
|
@ -109,6 +115,7 @@ int pmax_boardtype; /* Mother board type */
|
|||
#define DTOPDEV 15
|
||||
#define DCDEV 16
|
||||
#define SCCDEV 17
|
||||
#define RCONSDEV 85
|
||||
|
||||
/*
|
||||
* Console I/O is redirected to the appropriate device, either a screen and
|
||||
|
@ -116,6 +123,7 @@ int pmax_boardtype; /* Mother board type */
|
|||
*/
|
||||
|
||||
extern struct consdev *cn_tab; /* Console I/O table... */
|
||||
extern void rcons_vputc __P((dev_t, int)); /* XXX */
|
||||
|
||||
struct consdev cd = {
|
||||
(void (*)(struct consdev *))0, /* probe */
|
||||
|
@ -127,19 +135,42 @@ struct consdev cd = {
|
|||
CN_DEAD,
|
||||
};
|
||||
|
||||
/* should be locals of consinit, but that's split in two til
|
||||
* new-style config of decstations is finished
|
||||
*/
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
|
||||
|
||||
int consprobetc __P((int prom_slot));
|
||||
int consprobeslot __P((caddr_t name, void *addr));
|
||||
void consinit __P((void));
|
||||
void xconsinit __P((void));
|
||||
|
||||
|
||||
extern struct tc_cpu_desc * cpu_tcdesc __P ((int cputype));
|
||||
|
||||
|
||||
int kbd;
|
||||
int pending_remcons = 0;
|
||||
|
||||
/*
|
||||
* Console initialization: called early on from main,
|
||||
* before vm init or startup. Do enough configuration
|
||||
* to choose and initialize a console.
|
||||
*/
|
||||
void
|
||||
consinit()
|
||||
{
|
||||
register int kbd, crt;
|
||||
int crt;
|
||||
register char *oscon;
|
||||
int screen = 0;
|
||||
|
||||
extern void (*v_putc) __P ((dev_t, int));
|
||||
cn_tab = &cd;
|
||||
(*callv -> _printf)("consinit\n");
|
||||
|
||||
|
||||
/*
|
||||
* First get the "osconsole" environment variable.
|
||||
|
@ -148,9 +179,11 @@ consinit()
|
|||
crt = kbd = -1;
|
||||
if (oscon && *oscon >= '0' && *oscon <= '9') {
|
||||
kbd = *oscon - '0';
|
||||
/*cn_tab.cn_pri = CN_DEAD;*/
|
||||
screen = 0;
|
||||
while (*++oscon) {
|
||||
if (*oscon == ',')
|
||||
/*cn_tab.cn_pri = CN_INTERNAL;*/
|
||||
screen = 1;
|
||||
else if (screen &&
|
||||
*oscon >= '0' && *oscon <= '9') {
|
||||
|
@ -160,6 +193,12 @@ consinit()
|
|||
}
|
||||
}
|
||||
}
|
||||
/* we can't do anything until auto-configuration
|
||||
* has run, and that requires kmalloc(), which
|
||||
* hasn't been initialized yet. Just keep using
|
||||
* whatever the PROM vector gave us.
|
||||
*/
|
||||
|
||||
if (pmax_boardtype == DS_PMAX && kbd == 1)
|
||||
screen = 1;
|
||||
/*
|
||||
|
@ -167,6 +206,7 @@ consinit()
|
|||
* osconsole to '1' like the PMAX.
|
||||
*/
|
||||
if (pmax_boardtype == DS_3MAX && crt == -1 && kbd == 1) {
|
||||
/* Try to use pmax onboard framebuffer */
|
||||
screen = 1;
|
||||
crt = 0;
|
||||
kbd = 7;
|
||||
|
@ -182,7 +222,8 @@ consinit()
|
|||
#if NDC > 0 && NPM > 0
|
||||
if (pminit()) {
|
||||
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
|
||||
cd.cn_getc = dcGetc;
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc);
|
||||
cd.cn_pri = CN_INTERNAL;
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +250,8 @@ consinit()
|
|||
#if NDC > 0
|
||||
if (kbd == 7) {
|
||||
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
|
||||
cd.cn_getc = dcGetc;
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc);
|
||||
} else
|
||||
#endif /* NDC */
|
||||
goto remcons;
|
||||
|
@ -220,7 +262,8 @@ consinit()
|
|||
#if NSCC > 0
|
||||
if (kbd == 3) {
|
||||
cd.cn_dev = makedev(SCCDEV, SCCKBD_PORT);
|
||||
cd.cn_getc = sccGetc;
|
||||
lk_divert(sccGetc);
|
||||
cd.cn_getc = LKgetc;
|
||||
} else
|
||||
#endif /* NSCC */
|
||||
goto remcons;
|
||||
|
@ -230,40 +273,52 @@ consinit()
|
|||
goto remcons;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check for a suitable turbochannel frame buffer.
|
||||
*/
|
||||
if (tc_slot_info[crt].driver_name) {
|
||||
#if NMFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "mfb") == 0 &&
|
||||
mfbinit(tc_slot_info[crt].k1seg_address)) {
|
||||
if (consprobetc(crt)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
#ifdef RCONS_HACK
|
||||
/* FIXME */ cd.cn_putc = v_putc;
|
||||
/* FIXME */ cd.cn_dev = makedev (RCONSDEV, 0);
|
||||
#endif /* RCONS_HACK */
|
||||
cd.cn_putc = rcons_vputc; /*XXX*/
|
||||
return;
|
||||
}
|
||||
#endif /* NMFB */
|
||||
#if NSFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "sfb") == 0 &&
|
||||
sfbinit(tc_slot_info[crt].k1seg_address, 0)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return;
|
||||
}
|
||||
#endif /* NSFB */
|
||||
#if NCFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "cfb") == 0 &&
|
||||
cfbinit(tc_slot_info[crt].k1seg_address)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return;
|
||||
}
|
||||
#endif /* NCFB */
|
||||
printf("crt: %s not supported as console device\n",
|
||||
tc_slot_info[crt].driver_name);
|
||||
} else
|
||||
printf("No crt console device in slot %d\n", crt);
|
||||
}
|
||||
|
||||
|
||||
remcons:
|
||||
|
||||
/*
|
||||
* Configure a serial port as a remote console.
|
||||
*/
|
||||
|
||||
/* XXX serial drivers need to be rewritten to handle
|
||||
* init this early. Defer switching to non-PROM
|
||||
* driver until later.
|
||||
*/
|
||||
pending_remcons = 1;
|
||||
printf("Using PROM serial output until serial drivers initialized\n");
|
||||
|
||||
/* We never cahnged output; go back to using PROM input */
|
||||
cd.cn_dev = makedev (0, 0);
|
||||
cd.cn_getc = /*(int (*)(dev_t)) */ romgetc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure a serial port as a remote console.
|
||||
*/
|
||||
void
|
||||
xconsinit()
|
||||
{
|
||||
if (!pending_remcons)
|
||||
return;
|
||||
|
||||
pending_remcons = 0;
|
||||
switch (pmax_boardtype) {
|
||||
case DS_PMAX:
|
||||
#if NDC > 0
|
||||
|
@ -309,6 +364,91 @@ remcons:
|
|||
printf("Can't configure console!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Probe for a framebuffer option card. Configure the first one
|
||||
* found as a console.
|
||||
*/
|
||||
int
|
||||
consprobetc(prom_slot)
|
||||
int prom_slot;
|
||||
{
|
||||
void *slotaddr;
|
||||
int slot;
|
||||
struct tc_cpu_desc * sc_desc = cpu_tcdesc(pmax_boardtype);
|
||||
char namebuf[20];
|
||||
|
||||
if (sc_desc == NULL)
|
||||
return;
|
||||
|
||||
/*printf("Looking for fb console in slot %d", slot);*/
|
||||
|
||||
/*
|
||||
* Try to configure each turbochannel (or CPU-internal) device.
|
||||
* Knows about gross internals of TurboChannel bus autoconfig
|
||||
* descriptor, which needs to be fixed badly.
|
||||
*/
|
||||
for (slot = 0; slot < sc_desc->tcd_ndevs; slot++) {
|
||||
slotaddr = (void *)sc_desc->tcd_slots[slot].tsd_dense;
|
||||
/*printf("probing slot %d at 0x%x\n", slot, slotaddr);*/
|
||||
|
||||
if (tc_checkdevmem(slotaddr) == 0)
|
||||
continue;
|
||||
if (tc_checkslot(slotaddr, namebuf) == 0)
|
||||
continue;
|
||||
|
||||
if (consprobeslot(namebuf, slotaddr))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try and configure one slot as framebuffer console.
|
||||
* Accept only the framebuffers configured in.
|
||||
*/
|
||||
int
|
||||
consprobeslot(name, addr)
|
||||
char *name;
|
||||
void * addr;
|
||||
|
||||
{
|
||||
|
||||
/*printf(", trying to init a \"%s\"", name);*/
|
||||
|
||||
#define DRIVER_FOR_SLOT(slotname, drivername) \
|
||||
(strcmp (slotname, drivername) == 0)
|
||||
|
||||
#if NMFB > 0
|
||||
if (DRIVER_FOR_SLOT(name, "PMAG-AA ") &&
|
||||
mfbinit(addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NMFB */
|
||||
|
||||
#if NSFB > 0
|
||||
if (DRIVER_FOR_SLOT(name, "PMAGB-BA") &&
|
||||
sfbinit(addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NSFB */
|
||||
|
||||
#if NCFB > 0
|
||||
/*"cfb"*/
|
||||
if (DRIVER_FOR_SLOT(name, "PMAG-BA ") &&
|
||||
cfbinit(NULL, addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NCFB */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get character from ROM console.
|
||||
*/
|
||||
|
@ -342,3 +482,33 @@ static void rompollc (dev, c)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
extern struct tty *constty; /* virtual console output device */
|
||||
extern struct consdev *cn_tab; /* physical console device info */
|
||||
extern struct vnode *cn_devvp; /* vnode for underlying device. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
pmax_cnselect(dev, rw, p)
|
||||
dev_t dev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
/*
|
||||
* Redirect the ioctl, if that's appropriate.
|
||||
* I don't want to think of the possible side effects
|
||||
* of console redirection here.
|
||||
*/
|
||||
if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
|
||||
dev = constty->t_dev;
|
||||
else if (cn_tab == NULL)
|
||||
return ENXIO;
|
||||
else
|
||||
dev = cn_tab->cn_dev;
|
||||
#ifdef RCONS
|
||||
if (cn_tab -> cn_dev == makedev (85, 0))
|
||||
return rconsselect (cn_tab -> cn_dev, rw, p);
|
||||
#endif
|
||||
return (ttselect(cn_tab->cn_dev, rw, p));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,632 @@
|
|||
/* $NetBSD: qvss_compat.c,v 1.1 1995/09/11 07:45:47 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* @(#)fb.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)";
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file has all the routines common to the various frame buffer drivers
|
||||
* including a generic ioctl routine. The pmax_fb structure is passed into the
|
||||
* routines and has device specifics stored in it.
|
||||
* The LK201 keycode mapping routine is also here along with initialization
|
||||
* functions for the keyboard and mouse.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
|
||||
#include <machine/pmioctl.h>
|
||||
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/fbvar.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
#include <pmax/dev/lk201.h>
|
||||
|
||||
/*#include <pmax/stand/dec_prom.h>*/
|
||||
|
||||
#include <pmax/pmax/cons.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
|
||||
#include <dc.h>
|
||||
#include <scc.h>
|
||||
#include <dtop.h>
|
||||
|
||||
|
||||
/*
|
||||
* Forward / extern references.
|
||||
*/
|
||||
|
||||
extern void pmEventQueueInit __P((pmEventQueue *qe));
|
||||
void fbKbdEvent(), fbMouseEvent(), fbMouseButtons(), fbScroll();
|
||||
extern int pmax_boardtype;
|
||||
|
||||
|
||||
#if NDC > 0
|
||||
extern void (*dcDivertXInput)();
|
||||
extern void (*dcMouseEvent)();
|
||||
extern void (*dcMouseButtons)();
|
||||
#endif
|
||||
#if NSCC > 0
|
||||
extern void (*sccDivertXInput)();
|
||||
extern void (*sccMouseEvent)();
|
||||
extern void (*sccMouseButtons)();
|
||||
#endif
|
||||
#if NDTOP > 0
|
||||
extern void (*dtopDivertXInput)();
|
||||
extern void (*dtopMouseEvent)();
|
||||
extern void (*dtopMouseButtons)();
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 /*XXX*/
|
||||
#if NDC > 0
|
||||
#include <machine/dc7085cons.h>
|
||||
extern int dcGetc(), dcparam();
|
||||
extern void dcPutc();
|
||||
#endif
|
||||
#if NDTOP > 0
|
||||
#include <pmax/dev/dtopreg.h>
|
||||
extern void dtopKBDPutc();
|
||||
#endif
|
||||
#if NSCC > 0
|
||||
#include <pmax/dev/sccreg.h>
|
||||
extern int sccGetc(), sccparam();
|
||||
extern void sccPutc();
|
||||
#endif
|
||||
|
||||
#endif /* 0 */
|
||||
extern struct fbinfo *firstfi;
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the old-style pmax framebuffer structure from a new-style
|
||||
* rcons structure. Can die when all the old style pmax_fb structures
|
||||
* are gone. Note that the QVSS/pm mapped event buffer includes the
|
||||
* fbu field initialized below.
|
||||
*/
|
||||
init_pmaxfbu(fi)
|
||||
struct fbinfo *fi;
|
||||
{
|
||||
|
||||
int tty_rows, tty_cols; /* rows, cols for glass-tty mode */
|
||||
register struct fbuaccess *fbu = NULL;
|
||||
|
||||
if (fi == NULL || fi->fi_fbu == NULL)
|
||||
panic("init_pmaxfb: given null pointer to framebuffer\n");
|
||||
|
||||
/* XXX don't rely on there being a pmax_fb struct */
|
||||
fbu = fi->fi_fbu;
|
||||
|
||||
|
||||
/* fb dimensions */
|
||||
fbu->scrInfo.max_x = fi->fi_type.fb_width;
|
||||
fbu->scrInfo.max_y = fi->fi_type.fb_height;
|
||||
fbu->scrInfo.max_cur_x = fbu->scrInfo.max_x - 1;
|
||||
fbu->scrInfo.max_cur_y = fbu->scrInfo.max_y - 1;
|
||||
|
||||
/* these have the same initial value on qvss-style framebuffers */
|
||||
fbu->scrInfo.version = 11;
|
||||
fbu->scrInfo.mthreshold = 4;
|
||||
fbu->scrInfo.mscale = 2;
|
||||
|
||||
/* this is not always right (pm on kn01) but it's a common case */
|
||||
fbu->scrInfo.min_cur_x = 0;
|
||||
fbu->scrInfo.min_cur_y = 0;
|
||||
|
||||
/*
|
||||
* Compute glass-tty dimensions. These don't belong here
|
||||
* anymore, but the Ultrix and 4.3+ bsd drivers put them
|
||||
* in the event structure mapped into user address space.
|
||||
*/
|
||||
|
||||
tty_cols = 80;
|
||||
|
||||
/* A guess, but correct for 1024x864, 1024x768 and 1280x1024 */
|
||||
tty_rows = (fi->fi_type.fb_height / 15) - 1;
|
||||
|
||||
if (tty_rows != fbu->scrInfo.max_row ||
|
||||
tty_cols != fbu->scrInfo.max_col)
|
||||
printf("framebuffer init: size mismatch",
|
||||
"given %dx%d, compute %dx%x\n",
|
||||
fbu->scrInfo.max_row, fbu->scrInfo.max_col,
|
||||
tty_rows, tty_cols);
|
||||
|
||||
pmEventQueueInit(&fi->fi_fbu->scrInfo.qe);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the qvss-style ringbuffer of mouse button/move
|
||||
* events to be empty. Called both when initializing the
|
||||
* console softc and on each new open of that device.
|
||||
*/
|
||||
void
|
||||
pmEventQueueInit(qe)
|
||||
pmEventQueue *qe;
|
||||
{
|
||||
qe->timestamp_ms = TO_MS(time);
|
||||
qe->eSize = PM_MAXEVQ;
|
||||
qe->eHead = qe->eTail = 0;
|
||||
qe->tcSize = MOTION_BUFFER_SIZE;
|
||||
qe->tcNext = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* fbKbdEvent --
|
||||
*
|
||||
* Process a received character.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Events added to the queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
fbKbdEvent(ch, fi)
|
||||
int ch;
|
||||
register struct fbinfo *fi;
|
||||
{
|
||||
register pmEvent *eventPtr;
|
||||
int i;
|
||||
register struct fbuaccess *fbu = NULL;
|
||||
|
||||
if (!fi->fi_open)
|
||||
return;
|
||||
|
||||
fbu = fi->fi_fbu;
|
||||
|
||||
/*
|
||||
* See if there is room in the queue.
|
||||
*/
|
||||
i = PM_EVROUND(fbu->scrInfo.qe.eTail + 1);
|
||||
if (i == fbu->scrInfo.qe.eHead)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Add the event to the queue.
|
||||
*/
|
||||
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
||||
eventPtr->type = BUTTON_RAW_TYPE;
|
||||
eventPtr->device = KEYBOARD_DEVICE;
|
||||
eventPtr->x = fbu->scrInfo.mouse.x;
|
||||
eventPtr->y = fbu->scrInfo.mouse.y;
|
||||
eventPtr->time = TO_MS(time);
|
||||
eventPtr->key = ch;
|
||||
fbu->scrInfo.qe.eTail = i;
|
||||
selwakeup(&fi->fi_selp);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* fbMouseEvent --
|
||||
*
|
||||
* Process a mouse event.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* An event is added to the event queue.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
fbMouseEvent(newRepPtr, fi)
|
||||
register MouseReport *newRepPtr;
|
||||
register struct fbinfo *fi;
|
||||
{
|
||||
unsigned milliSec;
|
||||
int i;
|
||||
pmEvent *eventPtr;
|
||||
register struct fbuaccess *fbu = NULL;
|
||||
|
||||
if (!fi->fi_open)
|
||||
return;
|
||||
|
||||
fbu = fi->fi_fbu;
|
||||
|
||||
milliSec = TO_MS(time);
|
||||
|
||||
/*
|
||||
* Check to see if we have to accelerate the mouse
|
||||
*/
|
||||
if (fbu->scrInfo.mscale >= 0) {
|
||||
if (newRepPtr->dx >= fbu->scrInfo.mthreshold) {
|
||||
newRepPtr->dx +=
|
||||
(newRepPtr->dx - fbu->scrInfo.mthreshold) *
|
||||
fbu->scrInfo.mscale;
|
||||
}
|
||||
if (newRepPtr->dy >= fbu->scrInfo.mthreshold) {
|
||||
newRepPtr->dy +=
|
||||
(newRepPtr->dy - fbu->scrInfo.mthreshold) *
|
||||
fbu->scrInfo.mscale;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update mouse position
|
||||
*/
|
||||
if (newRepPtr->state & MOUSE_X_SIGN) {
|
||||
fbu->scrInfo.mouse.x += newRepPtr->dx;
|
||||
if (fbu->scrInfo.mouse.x > fbu->scrInfo.max_cur_x)
|
||||
fbu->scrInfo.mouse.x = fbu->scrInfo.max_cur_x;
|
||||
} else {
|
||||
fbu->scrInfo.mouse.x -= newRepPtr->dx;
|
||||
if (fbu->scrInfo.mouse.x < fbu->scrInfo.min_cur_x)
|
||||
fbu->scrInfo.mouse.x = fbu->scrInfo.min_cur_x;
|
||||
}
|
||||
if (newRepPtr->state & MOUSE_Y_SIGN) {
|
||||
fbu->scrInfo.mouse.y -= newRepPtr->dy;
|
||||
if (fbu->scrInfo.mouse.y < fbu->scrInfo.min_cur_y)
|
||||
fbu->scrInfo.mouse.y = fbu->scrInfo.min_cur_y;
|
||||
} else {
|
||||
fbu->scrInfo.mouse.y += newRepPtr->dy;
|
||||
if (fbu->scrInfo.mouse.y > fbu->scrInfo.max_cur_y)
|
||||
fbu->scrInfo.mouse.y = fbu->scrInfo.max_cur_y;
|
||||
}
|
||||
|
||||
/*
|
||||
* Move the hardware cursor.
|
||||
*/
|
||||
(*fi->fi_driver->fbd_poscursor)
|
||||
(fi, fbu->scrInfo.mouse.x, fbu->scrInfo.mouse.y);
|
||||
|
||||
/*
|
||||
* Store the motion event in the motion buffer.
|
||||
*/
|
||||
fbu->tcs[fbu->scrInfo.qe.tcNext].time = milliSec;
|
||||
fbu->tcs[fbu->scrInfo.qe.tcNext].x = fbu->scrInfo.mouse.x;
|
||||
fbu->tcs[fbu->scrInfo.qe.tcNext].y = fbu->scrInfo.mouse.y;
|
||||
if (++fbu->scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
|
||||
fbu->scrInfo.qe.tcNext = 0;
|
||||
if (fbu->scrInfo.mouse.y < fbu->scrInfo.mbox.bottom &&
|
||||
fbu->scrInfo.mouse.y >= fbu->scrInfo.mbox.top &&
|
||||
fbu->scrInfo.mouse.x < fbu->scrInfo.mbox.right &&
|
||||
fbu->scrInfo.mouse.x >= fbu->scrInfo.mbox.left)
|
||||
return;
|
||||
|
||||
fbu->scrInfo.mbox.bottom = 0;
|
||||
if (PM_EVROUND(fbu->scrInfo.qe.eTail + 1) == fbu->scrInfo.qe.eHead)
|
||||
return;
|
||||
|
||||
i = PM_EVROUND(fbu->scrInfo.qe.eTail - 1);
|
||||
if ((fbu->scrInfo.qe.eTail != fbu->scrInfo.qe.eHead) &&
|
||||
(i != fbu->scrInfo.qe.eHead)) {
|
||||
pmEvent *eventPtr;
|
||||
|
||||
eventPtr = &fbu->events[i];
|
||||
if (eventPtr->type == MOTION_TYPE) {
|
||||
eventPtr->x = fbu->scrInfo.mouse.x;
|
||||
eventPtr->y = fbu->scrInfo.mouse.y;
|
||||
eventPtr->time = milliSec;
|
||||
eventPtr->device = MOUSE_DEVICE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Put event into queue and wakeup any waiters.
|
||||
*/
|
||||
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
||||
eventPtr->type = MOTION_TYPE;
|
||||
eventPtr->time = milliSec;
|
||||
eventPtr->x = fbu->scrInfo.mouse.x;
|
||||
eventPtr->y = fbu->scrInfo.mouse.y;
|
||||
eventPtr->device = MOUSE_DEVICE;
|
||||
fbu->scrInfo.qe.eTail = PM_EVROUND(fbu->scrInfo.qe.eTail + 1);
|
||||
selwakeup(&fi->fi_selp);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* fbMouseButtons --
|
||||
*
|
||||
* Process mouse buttons.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
fbMouseButtons(newRepPtr, fi)
|
||||
MouseReport *newRepPtr;
|
||||
register struct fbinfo *fi;
|
||||
{
|
||||
static char temp, oldSwitch, newSwitch;
|
||||
int i, j;
|
||||
pmEvent *eventPtr;
|
||||
static MouseReport lastRep;
|
||||
register struct fbuaccess *fbu = NULL;
|
||||
|
||||
if (!fi->fi_open)
|
||||
return;
|
||||
|
||||
fbu = fi->fi_fbu;
|
||||
|
||||
newSwitch = newRepPtr->state & 0x07;
|
||||
oldSwitch = lastRep.state & 0x07;
|
||||
|
||||
temp = oldSwitch ^ newSwitch;
|
||||
if (temp == 0)
|
||||
return;
|
||||
for (j = 1; j < 8; j <<= 1) {
|
||||
if ((j & temp) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Check for room in the queue
|
||||
*/
|
||||
i = PM_EVROUND(fbu->scrInfo.qe.eTail+1);
|
||||
if (i == fbu->scrInfo.qe.eHead)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Put event into queue.
|
||||
*/
|
||||
eventPtr = &fbu->events[fbu->scrInfo.qe.eTail];
|
||||
|
||||
switch (j) {
|
||||
case RIGHT_BUTTON:
|
||||
eventPtr->key = EVENT_RIGHT_BUTTON;
|
||||
break;
|
||||
|
||||
case MIDDLE_BUTTON:
|
||||
eventPtr->key = EVENT_MIDDLE_BUTTON;
|
||||
break;
|
||||
|
||||
case LEFT_BUTTON:
|
||||
eventPtr->key = EVENT_LEFT_BUTTON;
|
||||
}
|
||||
if (newSwitch & j)
|
||||
eventPtr->type = BUTTON_DOWN_TYPE;
|
||||
else
|
||||
eventPtr->type = BUTTON_UP_TYPE;
|
||||
eventPtr->device = MOUSE_DEVICE;
|
||||
|
||||
eventPtr->time = TO_MS(time);
|
||||
eventPtr->x = fbu->scrInfo.mouse.x;
|
||||
eventPtr->y = fbu->scrInfo.mouse.y;
|
||||
fbu->scrInfo.qe.eTail = i;
|
||||
}
|
||||
selwakeup(&fi->fi_selp);
|
||||
|
||||
lastRep = *newRepPtr;
|
||||
fbu->scrInfo.mswitches = newSwitch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use vm_mmap() to map the frame buffer and shared data into the user's
|
||||
* address space.
|
||||
* Return errno if there was an error.
|
||||
*/
|
||||
fbmmap_fb(fi, dev, data, p)
|
||||
struct fbinfo *fi;
|
||||
dev_t dev;
|
||||
caddr_t data;
|
||||
struct proc *p;
|
||||
{
|
||||
int error;
|
||||
vm_offset_t addr;
|
||||
vm_size_t len;
|
||||
struct vnode vn;
|
||||
struct specinfo si;
|
||||
struct fbuaccess *fbp;
|
||||
register struct fbuaccess *fbu = fi->fi_fbu;
|
||||
|
||||
len = pmax_round_page(((vm_offset_t)fbu & PGOFSET) +
|
||||
sizeof(struct fbuaccess)) +
|
||||
pmax_round_page(fi->fi_type.fb_size);
|
||||
addr = (vm_offset_t)0x20000000; /* XXX */
|
||||
vn.v_type = VCHR; /* XXX */
|
||||
vn.v_specinfo = &si; /* XXX */
|
||||
vn.v_rdev = dev; /* XXX */
|
||||
/*
|
||||
* Map the all the data the user needs access to into
|
||||
* user space.
|
||||
*/
|
||||
error = vm_mmap(&p->p_vmspace->vm_map, &addr, len,
|
||||
VM_PROT_ALL, VM_PROT_ALL, MAP_SHARED, (caddr_t)&vn,
|
||||
(vm_offset_t)0);
|
||||
if (error)
|
||||
return (error);
|
||||
fbp = (struct fbuaccess *)(addr + ((vm_offset_t)fbu & PGOFSET));
|
||||
*(PM_Info **)data = &fbp->scrInfo;
|
||||
fbu->scrInfo.qe.events = fbp->events;
|
||||
fbu->scrInfo.qe.tcs = fbp->tcs;
|
||||
fbu->scrInfo.planemask = (char *)0;
|
||||
/*
|
||||
* Map the frame buffer into the user's address space.
|
||||
*/
|
||||
fbu->scrInfo.bitmap = (char *)pmax_round_page(fbp + 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic functions for keyboard and mouse input.
|
||||
* Just use the "generic" qvss/pm-compatible functions above, but pass them
|
||||
* the soft state for the first framebuffer found on this system.
|
||||
* We don't support more than one mouse, even for multiple
|
||||
* framebuffers, so this should be adequate.
|
||||
* It also relieves each fb driver from having to provide its own
|
||||
* version of these functions.
|
||||
*
|
||||
* TODO: change the callers of these to pass a pointer to the struct fbinfo,
|
||||
* thus finessing the problem.
|
||||
*/
|
||||
|
||||
void
|
||||
genKbdEvent(ch)
|
||||
int ch;
|
||||
{
|
||||
fbKbdEvent(ch, firstfi);
|
||||
}
|
||||
|
||||
void
|
||||
genMouseEvent(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
{
|
||||
fbMouseEvent(newRepPtr, firstfi);
|
||||
}
|
||||
|
||||
void
|
||||
genMouseButtons(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
{
|
||||
fbMouseButtons(newRepPtr, firstfi);
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure the mouse and keyboard based on machine type
|
||||
*/
|
||||
void
|
||||
genConfigMouse()
|
||||
{
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
switch (pmax_boardtype) {
|
||||
#if NDC > 0
|
||||
case DS_3MAX:
|
||||
case DS_PMAX:
|
||||
dcDivertXInput = genKbdEvent;
|
||||
dcMouseEvent = genMouseEvent;
|
||||
dcMouseButtons = genMouseButtons;
|
||||
break;
|
||||
#endif
|
||||
#if NSCC > 1
|
||||
case DS_3MIN:
|
||||
case DS_3MAXPLUS:
|
||||
sccDivertXInput = genKbdEvent;
|
||||
sccMouseEvent = genMouseEvent;
|
||||
sccMouseButtons = genMouseButtons;
|
||||
break;
|
||||
#endif
|
||||
#if NDTOP > 0
|
||||
case DS_MAXINE:
|
||||
dtopDivertXInput = genKbdEvent;
|
||||
dtopMouseEvent = genMouseEvent;
|
||||
dtopMouseButtons = genMouseButtons;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("Can't configure mouse/keyboard\n");
|
||||
};
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* and deconfigure them
|
||||
*/
|
||||
void
|
||||
genDeconfigMouse()
|
||||
{
|
||||
int s;
|
||||
|
||||
s = spltty();
|
||||
switch (pmax_boardtype) {
|
||||
#if NDC > 0
|
||||
case DS_3MAX:
|
||||
case DS_PMAX:
|
||||
dcDivertXInput = (void (*)())0;
|
||||
dcMouseEvent = (void (*)())0;
|
||||
dcMouseButtons = (void (*)())0;
|
||||
break;
|
||||
#endif
|
||||
#if NSCC > 1
|
||||
case DS_3MIN:
|
||||
case DS_3MAXPLUS:
|
||||
sccDivertXInput = (void (*)())0;
|
||||
sccMouseEvent = (void (*)())0;
|
||||
sccMouseButtons = (void (*)())0;
|
||||
break;
|
||||
#endif
|
||||
#if NDTOP > 0
|
||||
case DS_MAXINE:
|
||||
dtopDivertXInput = (void (*)())0;
|
||||
dtopMouseEvent = (void (*)())0;
|
||||
dtopMouseButtons = (void (*)())0;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("Can't deconfigure mouse/keyboard\n");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* And a mouse-report handler for redirected mouse input.
|
||||
*/
|
||||
|
||||
#include "dec_mouse.c"
|
|
@ -1,13 +1,11 @@
|
|||
/* $NetBSD: rcons.c,v 1.2 1995/04/21 01:24:33 mellon Exp $ */
|
||||
/* $NetBSD: rcons.c,v 1.3 1995/09/11 07:45:48 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
* Copyright (c) 1992, 1993
|
||||
* Copyright (c) 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department and Ralph Campbell.
|
||||
* Ted Lemon.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
@ -37,11 +35,11 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: Utah Hdr: cons.c 1.1 90/07/09
|
||||
*
|
||||
* @(#)cons.c 8.2 (Berkeley) 1/11/94
|
||||
*/
|
||||
|
||||
#include <rcons.h>
|
||||
#if NRCONS > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -49,11 +47,12 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <pmax/stand/dec_prom.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/sccreg.h>
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
|
@ -65,16 +64,15 @@
|
|||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/machConst.h>
|
||||
#include <machine/pmioctl.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <machine/fbio.h>
|
||||
#include <sparc/rcons/raster.h>
|
||||
#include <machine/fbvar.h>
|
||||
|
||||
#include <rcons.h>
|
||||
#include <machine/machConst.h>
|
||||
#include <machine/pmioctl.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
|
||||
/*
|
||||
* Console I/O is redirected to the appropriate device, either a screen and
|
||||
|
@ -86,6 +84,11 @@ struct tty *fbconstty; /* Frame buffer console tty... */
|
|||
struct tty rcons_tty [NRCONS]; /* Console tty struct... */
|
||||
extern struct consdev *cn_tab; /* Console I/O table... */
|
||||
|
||||
struct vnode *cn_in_devvp; /* vnode for underlying input device. */
|
||||
dev_t cn_in_dev = NODEV; /* console input device. */
|
||||
|
||||
char rcons_maxcols [20];
|
||||
|
||||
/* rcons_connect is called by fbconnect when the first frame buffer is
|
||||
attached. That frame buffer will always be the console frame buffer. */
|
||||
|
||||
|
@ -94,7 +97,11 @@ rcons_connect (info)
|
|||
{
|
||||
static struct fbdevice fb;
|
||||
static int row, col;
|
||||
extern int (*v_putc)(int);
|
||||
|
||||
/* If we're running a serial console, don't set up a raster console
|
||||
even if there's a device that can support it. */
|
||||
if (cn_tab -> cn_pri == CN_REMOTE)
|
||||
return;
|
||||
|
||||
fbconstty = &rcons_tty [0];
|
||||
fbconstty->t_dev = makedev(85, 0); /* /dev/console */
|
||||
|
@ -112,24 +119,52 @@ rcons_connect (info)
|
|||
fb.fb_p0 = 0;
|
||||
fb.fb_p1 = 0;
|
||||
|
||||
row = 0; col = 0;
|
||||
fb.fb_row = &row;
|
||||
fb.fb_col = &col;
|
||||
|
||||
fb.fb_maxrow = 80;
|
||||
fb.fb_maxcol = 34;
|
||||
#define HW_FONT_WIDTH 8
|
||||
#define HW_FONT_HEIGHT 15
|
||||
sprintf (rcons_maxcols, "%d", fb.fb_type.fb_height / HW_FONT_HEIGHT);
|
||||
row = (fb.fb_type.fb_height / HW_FONT_HEIGHT) - 1;
|
||||
col = 0;
|
||||
rcons_init (&fb);
|
||||
|
||||
cn_tab -> cn_putc = v_putc;
|
||||
cn_tab -> cn_dev = makedev (85, 0);
|
||||
/* constty = fbconstty; */
|
||||
fb.fb_xorigin = 0;
|
||||
fb.fb_yorigin = 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
rconsattach (n)
|
||||
int n;
|
||||
{
|
||||
printf ("rcons%d\n", n);
|
||||
register struct tty *tp = &rcons_tty [0];
|
||||
int status;
|
||||
|
||||
/* Set up the tty queues now... */
|
||||
clalloc(&tp->t_rawq, 1024, 1);
|
||||
clalloc(&tp->t_canq, 1024, 1);
|
||||
/* output queue doesn't need quoting */
|
||||
clalloc(&tp->t_outq, 1024, 0);
|
||||
#ifdef DEBUG
|
||||
printf("rconsattach: %d raster consoles\n", n);
|
||||
#endif
|
||||
|
||||
/* Try to set up the input device... */
|
||||
if (cn_in_dev != NODEV && cn_in_devvp == NULLVP) {
|
||||
/* try to get a reference on its vnode, but fail silently */
|
||||
cdevvp(cn_in_dev, &cn_in_devvp);
|
||||
status = ((*cdevsw[major(cn_in_dev)].d_open)
|
||||
(cn_in_dev, O_NONBLOCK, S_IFCHR, curproc)); /* XXX */
|
||||
if (status)
|
||||
printf ("rconsattach: input device open failed: %d\n",
|
||||
status);
|
||||
}
|
||||
/* Now the input side has been opened cleanly, we can dispense
|
||||
* with any special-case console input hacks, and point the
|
||||
* console device at rcons.
|
||||
*/
|
||||
/* FIXME */ cn_tab->cn_dev = makedev (/*RCONSDEV*/85, 0);
|
||||
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -140,14 +175,7 @@ rconsopen(dev, flag, mode, p)
|
|||
{
|
||||
register struct tty *tp = &rcons_tty [0];
|
||||
static int firstopen = 1;
|
||||
|
||||
if(firstopen) {
|
||||
clalloc(&tp->t_rawq, 1024, 1);
|
||||
clalloc(&tp->t_canq, 1024, 1);
|
||||
/* output queue doesn't need quoting */
|
||||
clalloc(&tp->t_outq, 1024, 0);
|
||||
firstopen = 0;
|
||||
}
|
||||
int status;
|
||||
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
/*
|
||||
|
@ -163,7 +191,9 @@ rconsopen(dev, flag, mode, p)
|
|||
ttsetwater(tp);
|
||||
} else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
return ((*linesw[tp->t_line].l_open)(dev, tp));
|
||||
|
||||
status = (*linesw[tp->t_line].l_open)(dev, tp);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -173,9 +203,11 @@ rconsclose(dev, flag, mode, p)
|
|||
struct proc *p;
|
||||
{
|
||||
register struct tty *tp = &rcons_tty [0];
|
||||
struct vnode *vp;
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -228,7 +260,7 @@ rconsioctl(dev, cmd, data, flag, p)
|
|||
return (ENOTTY);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
/* ARGSUSED */
|
||||
rconsstop (tp, rw)
|
||||
struct tty *tp;
|
||||
int rw;
|
||||
|
@ -261,3 +293,22 @@ rconsstrategy(bp)
|
|||
struct buf *bp;
|
||||
{
|
||||
}
|
||||
|
||||
/* Called by real input device when there is input for rcons. Passes
|
||||
input through line discpline interrupt routine... */
|
||||
|
||||
rcons_input (dev, ic)
|
||||
dev_t dev;
|
||||
int ic;
|
||||
{
|
||||
struct tty *tp;
|
||||
int unit = minor (dev);
|
||||
if (unit > NRCONS)
|
||||
return;
|
||||
tp = &rcons_tty [unit];
|
||||
if (!(tp -> t_state & TS_ISOPEN)) {
|
||||
return;
|
||||
}
|
||||
(*linesw [tp -> t_line].l_rint)(ic, tp);
|
||||
}
|
||||
#endif /* NRCONS > 0 */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: xcfb.c,v 1.6 1995/08/10 04:21:35 jonathan Exp $ */
|
||||
/* $NetBSD: xcfb.c,v 1.7 1995/09/11 07:45:42 jonathan Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -80,6 +80,8 @@
|
|||
* v 9.2 90/02/13 22:16:24 shirriff Exp SPRITE (DECWRL)";
|
||||
*/
|
||||
|
||||
#include <fb.h>
|
||||
|
||||
#include <xcfb.h>
|
||||
#include <dtop.h>
|
||||
#if NXCFB > 0
|
||||
|
@ -103,45 +105,67 @@ xcfb needs dtop device
|
|||
#include <machine/machConst.h>
|
||||
#include <machine/pmioctl.h>
|
||||
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <machine/fbio.h>
|
||||
#include <machine/fbvar.h>
|
||||
|
||||
#include <pmax/pmax/cons.h>
|
||||
|
||||
#include <pmax/dev/xcfbreg.h>
|
||||
#include <pmax/dev/ims332.h>
|
||||
#include <pmax/pmax/maxine.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/xcfbreg.h>
|
||||
#include <pmax/dev/dtopreg.h>
|
||||
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
|
||||
/*
|
||||
* These need to be mapped into user space.
|
||||
*/
|
||||
struct fbuaccess xcfbu;
|
||||
struct pmax_fb xcfbfb;
|
||||
|
||||
|
||||
/*
|
||||
* rcons methods and globals.
|
||||
*/
|
||||
struct pmax_fbtty xcfbfb;
|
||||
|
||||
struct fbinfo xcfbfi; /*XXX*/
|
||||
extern struct cfdriver cfb;
|
||||
|
||||
#define CMAP_BITS (3 * 256) /* 256 entries, 3 bytes per. */
|
||||
static u_char cmap_bits [NXCFB * CMAP_BITS]; /* One colormap per cfb... */
|
||||
|
||||
#define XCFB_FB_SIZE 0x100000 /* size of raster (mapped into userspace) */
|
||||
|
||||
|
||||
struct fbdriver xcfb_driver = {
|
||||
ims332_video_on,
|
||||
ims332_video_off,
|
||||
ims332InitColorMap,
|
||||
ims332GetColorMap,
|
||||
ims332LoadColorMap,
|
||||
ims332PosCursor,
|
||||
ims332LoadCursor,
|
||||
ims332CursorColor
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Forward references.
|
||||
*/
|
||||
static void xcfbScreenInit __P(());
|
||||
static void xcfbLoadCursor __P((u_short *ptr));
|
||||
static void xcfbRestoreCursorColor __P(());
|
||||
static void xcfbCursorColor __P((u_int *color));
|
||||
void xcfbPosCursor __P((int x, int y));
|
||||
static void xcfbInitColorMap __P(());
|
||||
static void xcfbLoadColorMap __P ((ColorMap *ptr));
|
||||
static u_int ims332_read_register();
|
||||
static void ims332_write_register();
|
||||
static void ims332_load_colormap_entry();
|
||||
static void ims332_video_off();
|
||||
static void ims332_video_on();
|
||||
extern void fbScreenInit __P((struct fbinfo *fi));
|
||||
|
||||
|
||||
void genKbdEvent(), genMouseEvent(), genMouseButtons();
|
||||
|
||||
void xcfbKbdEvent(), xcfbMouseEvent(), xcfbMouseButtons();
|
||||
extern void dtopKBDPutc();
|
||||
extern void (*dtopDivertXInput)();
|
||||
extern void (*dtopMouseEvent)();
|
||||
extern void (*dtopMouseButtons)();
|
||||
extern int pmax_boardtype;
|
||||
extern u_short defCursor[32];
|
||||
extern struct consdev cn_tab;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -187,606 +211,103 @@ xcfbattach(parent, self, aux)
|
|||
{
|
||||
struct confargs *ca = aux;
|
||||
|
||||
if (!xcfbinit(BUS_CVTADDR(ca)))
|
||||
if (!xcfbinit(BUS_CVTADDR(ca), self->dv_unit, 0));
|
||||
return;
|
||||
|
||||
/* mark slot as potential console */
|
||||
framebuffer_in_slot(ca->ca_slotpri);
|
||||
|
||||
/* no interrupts for XCFB */
|
||||
/*BUS_INTR_ESTABLISH(ca, sccintr, self->dv_unit);*/
|
||||
/*BUS_INTR_ESTABLISH(ca, xcfbintr, self->dv_unit);*/
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
xcfbopen(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
int s;
|
||||
|
||||
if (!fp->initialized)
|
||||
return (ENXIO);
|
||||
if (fp->GraphicsOpen)
|
||||
return (EBUSY);
|
||||
|
||||
fp->GraphicsOpen = 1;
|
||||
xcfbInitColorMap();
|
||||
/*
|
||||
* 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);
|
||||
s = spltty();
|
||||
dtopDivertXInput = xcfbKbdEvent;
|
||||
dtopMouseEvent = xcfbMouseEvent;
|
||||
dtopMouseButtons = xcfbMouseButtons;
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
xcfbclose(dev, flag)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
{
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
int s;
|
||||
|
||||
if (!fp->GraphicsOpen)
|
||||
return (EBADF);
|
||||
|
||||
fp->GraphicsOpen = 0;
|
||||
xcfbInitColorMap();
|
||||
s = spltty();
|
||||
dtopDivertXInput = (void (*)())0;
|
||||
dtopMouseEvent = (void (*)())0;
|
||||
dtopMouseButtons = (void (*)())0;
|
||||
splx(s);
|
||||
xcfbScreenInit();
|
||||
bzero((caddr_t)fp->fr_addr, 1024 * 768);
|
||||
xcfbPosCursor(fp->col * 8, fp->row * 15);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
xcfbioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
caddr_t data;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
int s;
|
||||
|
||||
switch (cmd) {
|
||||
case QIOCGINFO:
|
||||
return (fbmmap(fp, dev, data, p));
|
||||
|
||||
case QIOCPMSTATE:
|
||||
/*
|
||||
* Set mouse state.
|
||||
*/
|
||||
fp->fbu->scrInfo.mouse = *(pmCursor *)data;
|
||||
xcfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
|
||||
break;
|
||||
|
||||
case QIOCINIT:
|
||||
/*
|
||||
* Initialize the screen.
|
||||
*/
|
||||
xcfbScreenInit();
|
||||
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:
|
||||
xcfbLoadCursor((unsigned short *)data);
|
||||
break;
|
||||
|
||||
case QIOWCURSORCOLOR:
|
||||
xcfbCursorColor((unsigned int *)data);
|
||||
break;
|
||||
|
||||
case QIOSETCMAP:
|
||||
xcfbLoadColorMap((ColorMap *)data);
|
||||
break;
|
||||
|
||||
case QIOKERNLOOP:
|
||||
s = spltty();
|
||||
dtopDivertXInput = xcfbKbdEvent;
|
||||
dtopMouseEvent = xcfbMouseEvent;
|
||||
dtopMouseButtons = xcfbMouseButtons;
|
||||
splx(s);
|
||||
break;
|
||||
|
||||
case QIOKERNUNLOOP:
|
||||
s = spltty();
|
||||
dtopDivertXInput = (void (*)())0;
|
||||
dtopMouseEvent = (void (*)())0;
|
||||
dtopMouseButtons = (void (*)())0;
|
||||
splx(s);
|
||||
break;
|
||||
|
||||
case QIOVIDEOON:
|
||||
xcfbRestoreCursorColor();
|
||||
ims332_video_on();
|
||||
break;
|
||||
|
||||
case QIOVIDEOOFF:
|
||||
ims332_video_off();
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("xcfb0: Unknown ioctl command %x\n", cmd);
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the physical page number that corresponds to byte offset 'off'.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
xcfbmmap(dev, off, prot)
|
||||
dev_t dev;
|
||||
{
|
||||
int len;
|
||||
|
||||
len = pmax_round_page(((vm_offset_t)&xcfbu & PGOFSET) + sizeof(xcfbu));
|
||||
if (off < len)
|
||||
return pmax_btop(MACH_CACHED_TO_PHYS(&xcfbu) + off);
|
||||
off -= len;
|
||||
if (off >= xcfbfb.fr_size)
|
||||
return (-1);
|
||||
return pmax_btop(MACH_UNCACHED_TO_PHYS(xcfbfb.fr_addr) + off);
|
||||
}
|
||||
|
||||
xcfbselect(dev, flag, p)
|
||||
dev_t dev;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct pmax_fb *fp = &xcfbfb;
|
||||
|
||||
switch (flag) {
|
||||
case FREAD:
|
||||
if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
|
||||
return (1);
|
||||
selrecord(p, &fp->selp);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static u_char cursor_RGB[6]; /* cursor color 2 & 3 */
|
||||
|
||||
/*
|
||||
* Routines for the Inmos IMS-G332 Colour video controller
|
||||
* Author: Alessandro Forin, Carnegie Mellon University
|
||||
*/
|
||||
static u_int
|
||||
ims332_read_register(regno)
|
||||
{
|
||||
register u_char *regs = (u_char *)IMS332_ADDRESS;
|
||||
unsigned char *rptr;
|
||||
register u_int val, v1;
|
||||
|
||||
/* spec sez: */
|
||||
rptr = regs + 0x80000 + (regno << 4);
|
||||
val = *((volatile u_short *) rptr );
|
||||
v1 = *((volatile u_short *) regs );
|
||||
|
||||
return (val & 0xffff) | ((v1 & 0xff00) << 8);
|
||||
}
|
||||
|
||||
static void
|
||||
ims332_write_register(regno, val)
|
||||
register unsigned int val;
|
||||
{
|
||||
register u_char *regs = (u_char *)IMS332_ADDRESS;
|
||||
u_char *wptr;
|
||||
|
||||
/* spec sez: */
|
||||
wptr = regs + 0xa0000 + (regno << 4);
|
||||
*((volatile u_int *)(regs)) = (val >> 8) & 0xff00;
|
||||
*((volatile u_short *)(wptr)) = val;
|
||||
}
|
||||
|
||||
#define assert_ims332_reset_bit(r) *r &= ~0x40
|
||||
#define deassert_ims332_reset_bit(r) *r |= 0x40
|
||||
|
||||
/*
|
||||
* Color map
|
||||
*/
|
||||
static void
|
||||
xcfbLoadColorMap(ptr)
|
||||
ColorMap *ptr;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (ptr->index > 256)
|
||||
return;
|
||||
ims332_load_colormap_entry(ptr->index, ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
ims332_load_colormap_entry(entry, map)
|
||||
ColorMap *map;
|
||||
{
|
||||
/* ?? stop VTG */
|
||||
ims332_write_register(IMS332_REG_LUT_BASE + (entry & 0xff),
|
||||
(map->Entry.blue << 16) |
|
||||
(map->Entry.green << 8) |
|
||||
(map->Entry.red));
|
||||
}
|
||||
|
||||
static void
|
||||
xcfbInitColorMap()
|
||||
{
|
||||
register int i;
|
||||
ColorMap m;
|
||||
|
||||
m.Entry.red = m.Entry.green = m.Entry.blue = 0;
|
||||
ims332_load_colormap_entry(0, &m);
|
||||
|
||||
m.Entry.red = m.Entry.green = m.Entry.blue = 0xff;
|
||||
for (i = 1; i < 256; i++)
|
||||
ims332_load_colormap_entry(i, &m);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
cursor_RGB[i] = 0x00;
|
||||
cursor_RGB[i + 3] = 0xff;
|
||||
}
|
||||
xcfbRestoreCursorColor();
|
||||
}
|
||||
|
||||
/*
|
||||
* Video on/off
|
||||
*
|
||||
* It is unfortunate that X11 goes backward with white@0
|
||||
* and black@1. So we must stash away the zero-th entry
|
||||
* and fix it while screen is off. Also must remember
|
||||
* it, sigh.
|
||||
*/
|
||||
static struct {
|
||||
u_int save;
|
||||
int off;
|
||||
} xcfb_vstate;
|
||||
|
||||
static void
|
||||
ims332_video_off()
|
||||
{
|
||||
register u_int csr;
|
||||
|
||||
if (xcfb_vstate.off)
|
||||
return;
|
||||
|
||||
xcfb_vstate.save = ims332_read_register(IMS332_REG_LUT_BASE);
|
||||
|
||||
ims332_write_register(IMS332_REG_LUT_BASE, 0);
|
||||
|
||||
ims332_write_register(IMS332_REG_COLOR_MASK, 0);
|
||||
|
||||
/* cursor now */
|
||||
csr = ims332_read_register(IMS332_REG_CSR_A);
|
||||
csr |= IMS332_CSR_A_DISABLE_CURSOR;
|
||||
ims332_write_register(IMS332_REG_CSR_A, csr);
|
||||
|
||||
xcfb_vstate.off = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ims332_video_on()
|
||||
{
|
||||
register u_int csr;
|
||||
|
||||
if (!xcfb_vstate.off)
|
||||
return;
|
||||
|
||||
ims332_write_register(IMS332_REG_LUT_BASE, xcfb_vstate.save);
|
||||
|
||||
ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffffff);
|
||||
|
||||
/* cursor now */
|
||||
csr = ims332_read_register(IMS332_REG_CSR_A);
|
||||
csr &= ~IMS332_CSR_A_DISABLE_CURSOR;
|
||||
ims332_write_register(IMS332_REG_CSR_A, csr);
|
||||
|
||||
xcfb_vstate.off = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cursor
|
||||
*/
|
||||
void
|
||||
xcfbPosCursor(x, y)
|
||||
register int x, y;
|
||||
{
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
|
||||
if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
|
||||
y = fp->fbu->scrInfo.max_cur_y;
|
||||
if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
|
||||
x = fp->fbu->scrInfo.max_cur_x;
|
||||
fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
|
||||
fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
|
||||
ims332_write_register(IMS332_REG_CURSOR_LOC,
|
||||
((x & 0xfff) << 12) | (y & 0xfff));
|
||||
}
|
||||
|
||||
/*
|
||||
* xcfbRestoreCursorColor
|
||||
*/
|
||||
static void
|
||||
xcfbRestoreCursorColor()
|
||||
{
|
||||
|
||||
/* Bg is color[0], Fg is color[1] */
|
||||
ims332_write_register(IMS332_REG_CURSOR_LUT_0,
|
||||
(cursor_RGB[2] << 16) |
|
||||
(cursor_RGB[1] << 8) |
|
||||
(cursor_RGB[0]));
|
||||
ims332_write_register(IMS332_REG_CURSOR_LUT_1, 0x7f0000);
|
||||
ims332_write_register(IMS332_REG_CURSOR_LUT_2,
|
||||
(cursor_RGB[5] << 16) |
|
||||
(cursor_RGB[4] << 8) |
|
||||
(cursor_RGB[3]));
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* xcfbCursorColor --
|
||||
*
|
||||
* Set the color of the cursor.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
xcfbCursorColor(color)
|
||||
unsigned int color[];
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
cursor_RGB[i] = (u_char)(color[i] >> 8);
|
||||
|
||||
xcfbRestoreCursorColor();
|
||||
}
|
||||
|
||||
static void
|
||||
xcfbLoadCursor(cursor)
|
||||
u_short *cursor;
|
||||
{
|
||||
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 < 2) {
|
||||
out = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
out = ((out >> 2) & 0x3fff) |
|
||||
((ap & 0x1) << 15) |
|
||||
((bp & 0x1) << 14);
|
||||
ap >>= 1;
|
||||
bp >>= 1;
|
||||
}
|
||||
ims332_write_register(IMS332_REG_CURSOR_RAM + pos, out);
|
||||
pos++;
|
||||
j++;
|
||||
}
|
||||
while (j < 8) {
|
||||
ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0);
|
||||
pos++;
|
||||
j++;
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
while (pos < 512) {
|
||||
ims332_write_register(IMS332_REG_CURSOR_RAM + pos, 0);
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*/
|
||||
int
|
||||
xcfbinit()
|
||||
xcfbinit(base, unit, silent)
|
||||
caddr_t base;
|
||||
int unit;
|
||||
int silent;
|
||||
{
|
||||
register u_int *reset = (u_int *)IMS332_RESET_ADDRESS;
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
struct fbinfo *fi;
|
||||
|
||||
fp->isMono = 0;
|
||||
unit = 0; /*XXX*/ /* FIXME */
|
||||
|
||||
/*XXX*/
|
||||
/*
|
||||
* Or Cached? A comment in the Mach driver suggests that the X server
|
||||
* runs faster in cached address space, but the X server is going
|
||||
* to blow away the data cache whenever it updates the screen, so..
|
||||
*/
|
||||
fp->fr_addr = (char *)
|
||||
MACH_PHYS_TO_UNCACHED(XINE_PHYS_CFB_START + VRAM_OFFSET);
|
||||
fp->fr_size = 0x100000;
|
||||
base = (char *) MACH_PHYS_TO_UNCACHED(XINE_PHYS_CFB_START);
|
||||
|
||||
/* Fill in main frame buffer info struct. */
|
||||
fi->fi_unit = unit;
|
||||
fi->fi_pixels = (caddr_t)(base + VRAM_OFFSET);
|
||||
fi->fi_pixelsize = 1024 * 768;
|
||||
fi->fi_base = (caddr_t)IMS332_RESET_ADDRESS;
|
||||
fi->fi_vdac = (caddr_t)IMS332_ADDRESS;
|
||||
fi->fi_size = 0x100000;
|
||||
fi->fi_linebytes = 1024;
|
||||
fi->fi_driver = &xcfb_driver;
|
||||
fi->fi_blanked = 0;
|
||||
fi->fi_cmap_bits = (caddr_t)&cmap_bits [CMAP_BITS * unit];
|
||||
|
||||
/* Fill in Frame Buffer Type struct. */
|
||||
fi->fi_type.fb_boardtype = PMAX_FBTYPE_CFB;
|
||||
fi->fi_type.fb_width = 1024;
|
||||
fi->fi_type.fb_height = 768;
|
||||
fi->fi_type.fb_depth = 8;
|
||||
fi->fi_type.fb_cmsize = 256;
|
||||
fi->fi_type.fb_size = XCFB_FB_SIZE;
|
||||
|
||||
/*
|
||||
* qvss/pm-style mmap()ed event queue compatibility glue
|
||||
*/
|
||||
|
||||
/*
|
||||
* Must be in Uncached space since the fbuaccess structure is
|
||||
* mapped into the user's address space uncached.
|
||||
*/
|
||||
fp->fbu = (struct fbuaccess *)
|
||||
fi->fi_fbu = (struct fbuaccess *)
|
||||
MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&xcfbu));
|
||||
fp->posCursor = xcfbPosCursor;
|
||||
fp->KBDPutc = dtopKBDPutc;
|
||||
fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
|
||||
fi->fi_glasstty->KBDPutc = dtopKBDPutc;
|
||||
fi->fi_glasstty->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
|
||||
|
||||
/* This is glass-tty state but it's in the shared structure. Ick. */
|
||||
fi->fi_fbu->scrInfo.max_row = 50;
|
||||
fi->fi_fbu->scrInfo.max_col = 80;
|
||||
|
||||
init_pmaxfbu(fi);
|
||||
|
||||
/*
|
||||
* Initialize the screen.
|
||||
* Initialize old-style pmax glass-tty screen info.
|
||||
*/
|
||||
#ifdef notdef
|
||||
assert_ims332_reset_bit(reset);
|
||||
DELAY(1); /* specs sez 50ns.. */
|
||||
deassert_ims332_reset_bit(reset);
|
||||
fi->fi_glasstty = &xcfbfb;
|
||||
|
||||
/* CLOCKIN appears to receive a 6.25 Mhz clock --> PLL 12 for 75Mhz monitor */
|
||||
ims332_write_register(IMS332_REG_BOOT, 12 | IMS332_BOOT_CLOCK_PLL);
|
||||
/*XXX*/
|
||||
/* dimensions translated -15 pixels, for sprite origin? */
|
||||
fi->fi_fbu->scrInfo.max_cur_x = 1008;
|
||||
fi->fi_fbu->scrInfo.max_cur_y = 752;
|
||||
|
||||
/* initialize VTG */
|
||||
ims332_write_register(IMS332_REG_CSR_A,
|
||||
IMS332_BPP_8 | IMS332_CSR_A_DISABLE_CURSOR);
|
||||
DELAY(50); /* spec does not say */
|
||||
fi->fi_fbu->scrInfo.min_cur_x = -15;
|
||||
fi->fi_fbu->scrInfo.min_cur_y = -15;
|
||||
|
||||
/* datapath registers (values taken from prom's settings) */
|
||||
/* Initialize the RAMDAC. */
|
||||
ims332init (fi);
|
||||
|
||||
ims332_write_register(IMS332_REG_HALF_SYNCH, 0x10);
|
||||
ims332_write_register(IMS332_REG_BACK_PORCH, 0x21);
|
||||
ims332_write_register(IMS332_REG_DISPLAY, 0x100);
|
||||
ims332_write_register(IMS332_REG_SHORT_DIS, 0x5d);
|
||||
ims332_write_register(IMS332_REG_BROAD_PULSE, 0x9f);
|
||||
ims332_write_register(IMS332_REG_V_SYNC, 0xc);
|
||||
ims332_write_register(IMS332_REG_V_PRE_EQUALIZE, 2);
|
||||
ims332_write_register(IMS332_REG_V_POST_EQUALIZE, 2);
|
||||
ims332_write_register(IMS332_REG_V_BLANK, 0x2a);
|
||||
ims332_write_register(IMS332_REG_V_DISPLAY, 0x600);
|
||||
ims332_write_register(IMS332_REG_LINE_TIME, 0x146);
|
||||
ims332_write_register(IMS332_REG_LINE_START, 0x10);
|
||||
ims332_write_register(IMS332_REG_MEM_INIT, 0xa);
|
||||
ims332_write_register(IMS332_REG_XFER_DELAY, 0xa);
|
||||
|
||||
ims332_write_register(IMS332_REG_COLOR_MASK, 0xffffff);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize screen info.
|
||||
* Connect to the raster-console pseudo-driver
|
||||
*/
|
||||
fp->fbu->scrInfo.max_row = 50;
|
||||
fp->fbu->scrInfo.max_col = 80;
|
||||
fp->fbu->scrInfo.max_x = 1024;
|
||||
fp->fbu->scrInfo.max_y = 768;
|
||||
fp->fbu->scrInfo.max_cur_x = 1008;
|
||||
fp->fbu->scrInfo.max_cur_y = 752;
|
||||
fp->fbu->scrInfo.version = 11;
|
||||
fp->fbu->scrInfo.mthreshold = 4;
|
||||
fp->fbu->scrInfo.mscale = 2;
|
||||
fp->fbu->scrInfo.min_cur_x = -15;
|
||||
fp->fbu->scrInfo.min_cur_y = -15;
|
||||
fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
|
||||
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;
|
||||
|
||||
xcfbInitColorMap();
|
||||
|
||||
ims332_write_register(IMS332_REG_CSR_A,
|
||||
IMS332_BPP_8 | IMS332_CSR_A_DMA_DISABLE | IMS332_CSR_A_VTG_ENABLE);
|
||||
|
||||
xcfbScreenInit();
|
||||
fbScroll(fp);
|
||||
fbconnect("PMAG-DV", fi, silent);
|
||||
|
||||
#ifdef fpinitialized
|
||||
fp->initialized = 1;
|
||||
if (cn_tab.cn_fb == (struct pmax_fb *)0)
|
||||
cn_tab.cn_fb = fp;
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* xcfbScreenInit --
|
||||
*
|
||||
* Initialize the screen.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The screen is initialized.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
xcfbScreenInit()
|
||||
{
|
||||
register struct pmax_fb *fp = &xcfbfb;
|
||||
|
||||
/*
|
||||
* Home the cursor.
|
||||
* We want an LSI terminal emulation. We want the graphics
|
||||
* terminal to scroll from the bottom. So start at the bottom.
|
||||
*/
|
||||
fp->row = 49;
|
||||
fp->col = 0;
|
||||
|
||||
/*
|
||||
* Load the cursor with the default values
|
||||
*
|
||||
*/
|
||||
xcfbLoadCursor(defCursor);
|
||||
}
|
||||
|
||||
/*
|
||||
* xcfb keyboard and mouse input. Just punt to the generic ones in fb.c
|
||||
*/
|
||||
void
|
||||
xcfbKbdEvent(ch)
|
||||
int ch;
|
||||
{
|
||||
fbKbdEvent(ch, &xcfbfb);
|
||||
}
|
||||
|
||||
void
|
||||
xcfbMouseEvent(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
{
|
||||
fbMouseEvent(newRepPtr, &xcfbfb);
|
||||
}
|
||||
|
||||
void
|
||||
xcfbMouseButtons(newRepPtr)
|
||||
MouseReport *newRepPtr;
|
||||
{
|
||||
fbMouseButtons(newRepPtr, &xcfbfb);
|
||||
}
|
||||
#endif /* NDTOP */
|
||||
#endif /* NXCFB */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu_cons.c,v 1.1 1995/04/11 10:08:42 mellon Exp $ */
|
||||
/* $NetBSD: cpu_cons.c,v 1.2 1995/09/11 07:45:50 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,6 +43,8 @@
|
|||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/device.h>
|
||||
#include <dev/cons.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
|
@ -53,7 +55,6 @@
|
|||
|
||||
#include <pmax/stand/dec_prom.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/sccreg.h>
|
||||
#include <pmax/pmax/kn01.h>
|
||||
#include <pmax/pmax/kn02.h>
|
||||
|
@ -63,18 +64,20 @@
|
|||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/turbochannel.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
/* #include <pmax/pmax/cons.h> */
|
||||
#include <dev/cons.h>
|
||||
|
||||
#include <machine/machConst.h>
|
||||
#include <machine/pmioctl.h>
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <sys/device.h>
|
||||
#include <machine/fbio.h>
|
||||
#include <sparc/rcons/raster.h>
|
||||
#include <machine/fbvar.h>
|
||||
|
||||
#include <pmax/dev/fbreg.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <pmax/tc/tc.h>
|
||||
|
||||
|
||||
#include <pm.h>
|
||||
#include <cfb.h>
|
||||
#include <mfb.h>
|
||||
|
@ -87,6 +90,7 @@
|
|||
#include <asc.h>
|
||||
|
||||
#if NDC > 0
|
||||
#include <machine/dc7085cons.h>
|
||||
extern int dcGetc(), dcparam();
|
||||
extern void dcPutc();
|
||||
#endif
|
||||
|
@ -101,6 +105,8 @@ static int romgetc __P ((dev_t));
|
|||
static void romputc __P ((dev_t, int));
|
||||
static void rompollc __P((dev_t, int));
|
||||
|
||||
extern int LKgetc __P((dev_t dev)); /* should be in header file, but which one? */
|
||||
|
||||
int pmax_boardtype; /* Mother board type */
|
||||
|
||||
/*
|
||||
|
@ -109,6 +115,7 @@ int pmax_boardtype; /* Mother board type */
|
|||
#define DTOPDEV 15
|
||||
#define DCDEV 16
|
||||
#define SCCDEV 17
|
||||
#define RCONSDEV 85
|
||||
|
||||
/*
|
||||
* Console I/O is redirected to the appropriate device, either a screen and
|
||||
|
@ -116,6 +123,7 @@ int pmax_boardtype; /* Mother board type */
|
|||
*/
|
||||
|
||||
extern struct consdev *cn_tab; /* Console I/O table... */
|
||||
extern void rcons_vputc __P((dev_t, int)); /* XXX */
|
||||
|
||||
struct consdev cd = {
|
||||
(void (*)(struct consdev *))0, /* probe */
|
||||
|
@ -127,19 +135,42 @@ struct consdev cd = {
|
|||
CN_DEAD,
|
||||
};
|
||||
|
||||
/* should be locals of consinit, but that's split in two til
|
||||
* new-style config of decstations is finished
|
||||
*/
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
*/
|
||||
|
||||
|
||||
int consprobetc __P((int prom_slot));
|
||||
int consprobeslot __P((caddr_t name, void *addr));
|
||||
void consinit __P((void));
|
||||
void xconsinit __P((void));
|
||||
|
||||
|
||||
extern struct tc_cpu_desc * cpu_tcdesc __P ((int cputype));
|
||||
|
||||
|
||||
int kbd;
|
||||
int pending_remcons = 0;
|
||||
|
||||
/*
|
||||
* Console initialization: called early on from main,
|
||||
* before vm init or startup. Do enough configuration
|
||||
* to choose and initialize a console.
|
||||
*/
|
||||
void
|
||||
consinit()
|
||||
{
|
||||
register int kbd, crt;
|
||||
int crt;
|
||||
register char *oscon;
|
||||
int screen = 0;
|
||||
|
||||
extern void (*v_putc) __P ((dev_t, int));
|
||||
cn_tab = &cd;
|
||||
(*callv -> _printf)("consinit\n");
|
||||
|
||||
|
||||
/*
|
||||
* First get the "osconsole" environment variable.
|
||||
|
@ -148,9 +179,11 @@ consinit()
|
|||
crt = kbd = -1;
|
||||
if (oscon && *oscon >= '0' && *oscon <= '9') {
|
||||
kbd = *oscon - '0';
|
||||
/*cn_tab.cn_pri = CN_DEAD;*/
|
||||
screen = 0;
|
||||
while (*++oscon) {
|
||||
if (*oscon == ',')
|
||||
/*cn_tab.cn_pri = CN_INTERNAL;*/
|
||||
screen = 1;
|
||||
else if (screen &&
|
||||
*oscon >= '0' && *oscon <= '9') {
|
||||
|
@ -160,6 +193,12 @@ consinit()
|
|||
}
|
||||
}
|
||||
}
|
||||
/* we can't do anything until auto-configuration
|
||||
* has run, and that requires kmalloc(), which
|
||||
* hasn't been initialized yet. Just keep using
|
||||
* whatever the PROM vector gave us.
|
||||
*/
|
||||
|
||||
if (pmax_boardtype == DS_PMAX && kbd == 1)
|
||||
screen = 1;
|
||||
/*
|
||||
|
@ -167,6 +206,7 @@ consinit()
|
|||
* osconsole to '1' like the PMAX.
|
||||
*/
|
||||
if (pmax_boardtype == DS_3MAX && crt == -1 && kbd == 1) {
|
||||
/* Try to use pmax onboard framebuffer */
|
||||
screen = 1;
|
||||
crt = 0;
|
||||
kbd = 7;
|
||||
|
@ -182,7 +222,8 @@ consinit()
|
|||
#if NDC > 0 && NPM > 0
|
||||
if (pminit()) {
|
||||
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
|
||||
cd.cn_getc = dcGetc;
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc);
|
||||
cd.cn_pri = CN_INTERNAL;
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +250,8 @@ consinit()
|
|||
#if NDC > 0
|
||||
if (kbd == 7) {
|
||||
cd.cn_dev = makedev(DCDEV, DCKBD_PORT);
|
||||
cd.cn_getc = dcGetc;
|
||||
cd.cn_getc = LKgetc;
|
||||
lk_divert(dcGetc);
|
||||
} else
|
||||
#endif /* NDC */
|
||||
goto remcons;
|
||||
|
@ -220,7 +262,8 @@ consinit()
|
|||
#if NSCC > 0
|
||||
if (kbd == 3) {
|
||||
cd.cn_dev = makedev(SCCDEV, SCCKBD_PORT);
|
||||
cd.cn_getc = sccGetc;
|
||||
lk_divert(sccGetc);
|
||||
cd.cn_getc = LKgetc;
|
||||
} else
|
||||
#endif /* NSCC */
|
||||
goto remcons;
|
||||
|
@ -230,40 +273,52 @@ consinit()
|
|||
goto remcons;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check for a suitable turbochannel frame buffer.
|
||||
*/
|
||||
if (tc_slot_info[crt].driver_name) {
|
||||
#if NMFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "mfb") == 0 &&
|
||||
mfbinit(tc_slot_info[crt].k1seg_address)) {
|
||||
if (consprobetc(crt)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
#ifdef RCONS_HACK
|
||||
/* FIXME */ cd.cn_putc = v_putc;
|
||||
/* FIXME */ cd.cn_dev = makedev (RCONSDEV, 0);
|
||||
#endif /* RCONS_HACK */
|
||||
cd.cn_putc = rcons_vputc; /*XXX*/
|
||||
return;
|
||||
}
|
||||
#endif /* NMFB */
|
||||
#if NSFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "sfb") == 0 &&
|
||||
sfbinit(tc_slot_info[crt].k1seg_address, 0)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return;
|
||||
}
|
||||
#endif /* NSFB */
|
||||
#if NCFB > 0
|
||||
if (strcmp(tc_slot_info[crt].driver_name, "cfb") == 0 &&
|
||||
cfbinit(tc_slot_info[crt].k1seg_address)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return;
|
||||
}
|
||||
#endif /* NCFB */
|
||||
printf("crt: %s not supported as console device\n",
|
||||
tc_slot_info[crt].driver_name);
|
||||
} else
|
||||
printf("No crt console device in slot %d\n", crt);
|
||||
}
|
||||
|
||||
|
||||
remcons:
|
||||
|
||||
/*
|
||||
* Configure a serial port as a remote console.
|
||||
*/
|
||||
|
||||
/* XXX serial drivers need to be rewritten to handle
|
||||
* init this early. Defer switching to non-PROM
|
||||
* driver until later.
|
||||
*/
|
||||
pending_remcons = 1;
|
||||
printf("Using PROM serial output until serial drivers initialized\n");
|
||||
|
||||
/* We never cahnged output; go back to using PROM input */
|
||||
cd.cn_dev = makedev (0, 0);
|
||||
cd.cn_getc = /*(int (*)(dev_t)) */ romgetc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Configure a serial port as a remote console.
|
||||
*/
|
||||
void
|
||||
xconsinit()
|
||||
{
|
||||
if (!pending_remcons)
|
||||
return;
|
||||
|
||||
pending_remcons = 0;
|
||||
switch (pmax_boardtype) {
|
||||
case DS_PMAX:
|
||||
#if NDC > 0
|
||||
|
@ -309,6 +364,91 @@ remcons:
|
|||
printf("Can't configure console!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Probe for a framebuffer option card. Configure the first one
|
||||
* found as a console.
|
||||
*/
|
||||
int
|
||||
consprobetc(prom_slot)
|
||||
int prom_slot;
|
||||
{
|
||||
void *slotaddr;
|
||||
int slot;
|
||||
struct tc_cpu_desc * sc_desc = cpu_tcdesc(pmax_boardtype);
|
||||
char namebuf[20];
|
||||
|
||||
if (sc_desc == NULL)
|
||||
return;
|
||||
|
||||
/*printf("Looking for fb console in slot %d", slot);*/
|
||||
|
||||
/*
|
||||
* Try to configure each turbochannel (or CPU-internal) device.
|
||||
* Knows about gross internals of TurboChannel bus autoconfig
|
||||
* descriptor, which needs to be fixed badly.
|
||||
*/
|
||||
for (slot = 0; slot < sc_desc->tcd_ndevs; slot++) {
|
||||
slotaddr = (void *)sc_desc->tcd_slots[slot].tsd_dense;
|
||||
/*printf("probing slot %d at 0x%x\n", slot, slotaddr);*/
|
||||
|
||||
if (tc_checkdevmem(slotaddr) == 0)
|
||||
continue;
|
||||
if (tc_checkslot(slotaddr, namebuf) == 0)
|
||||
continue;
|
||||
|
||||
if (consprobeslot(namebuf, slotaddr))
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try and configure one slot as framebuffer console.
|
||||
* Accept only the framebuffers configured in.
|
||||
*/
|
||||
int
|
||||
consprobeslot(name, addr)
|
||||
char *name;
|
||||
void * addr;
|
||||
|
||||
{
|
||||
|
||||
/*printf(", trying to init a \"%s\"", name);*/
|
||||
|
||||
#define DRIVER_FOR_SLOT(slotname, drivername) \
|
||||
(strcmp (slotname, drivername) == 0)
|
||||
|
||||
#if NMFB > 0
|
||||
if (DRIVER_FOR_SLOT(name, "PMAG-AA ") &&
|
||||
mfbinit(addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NMFB */
|
||||
|
||||
#if NSFB > 0
|
||||
if (DRIVER_FOR_SLOT(name, "PMAGB-BA") &&
|
||||
sfbinit(addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NSFB */
|
||||
|
||||
#if NCFB > 0
|
||||
/*"cfb"*/
|
||||
if (DRIVER_FOR_SLOT(name, "PMAG-BA ") &&
|
||||
cfbinit(NULL, addr, 0, 1)) {
|
||||
cd.cn_pri = CN_NORMAL;
|
||||
return (1);
|
||||
}
|
||||
#endif /* NCFB */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Get character from ROM console.
|
||||
*/
|
||||
|
@ -342,3 +482,33 @@ static void rompollc (dev, c)
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
extern struct tty *constty; /* virtual console output device */
|
||||
extern struct consdev *cn_tab; /* physical console device info */
|
||||
extern struct vnode *cn_devvp; /* vnode for underlying device. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
pmax_cnselect(dev, rw, p)
|
||||
dev_t dev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
/*
|
||||
* Redirect the ioctl, if that's appropriate.
|
||||
* I don't want to think of the possible side effects
|
||||
* of console redirection here.
|
||||
*/
|
||||
if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
|
||||
dev = constty->t_dev;
|
||||
else if (cn_tab == NULL)
|
||||
return ENXIO;
|
||||
else
|
||||
dev = cn_tab->cn_dev;
|
||||
#ifdef RCONS
|
||||
if (cn_tab -> cn_dev == makedev (85, 0))
|
||||
return rconsselect (cn_tab -> cn_dev, rw, p);
|
||||
#endif
|
||||
return (ttselect(cn_tab->cn_dev, rw, p));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue