xref: /csrg-svn/sys/pmax/dev/mfb.c (revision 58793)
156815Sralph /*-
256815Sralph  * Copyright (c) 1992 The Regents of the University of California.
356815Sralph  * All rights reserved.
456815Sralph  *
556815Sralph  * This code is derived from software contributed to Berkeley by
656815Sralph  * Ralph Campbell and Rick Macklem.
756815Sralph  *
856815Sralph  * %sccs.include.redist.c%
956815Sralph  *
10*58793Sralph  *	@(#)mfb.c	7.3 (Berkeley) 03/23/93
1156815Sralph  */
1256815Sralph 
1356815Sralph /*
1456815Sralph  * Mach Operating System
1556815Sralph  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
1656815Sralph  * All Rights Reserved.
1756815Sralph  *
1856815Sralph  * Permission to use, copy, modify and distribute this software and its
1956815Sralph  * documentation is hereby granted, provided that both the copyright
2056815Sralph  * notice and this permission notice appear in all copies of the
2156815Sralph  * software, derivative works or modified versions, and any portions
2256815Sralph  * thereof, and that both notices appear in supporting documentation.
2356815Sralph  *
2456815Sralph  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
2556815Sralph  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
2656815Sralph  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
2756815Sralph  *
2856815Sralph  * Carnegie Mellon requests users of this software to return to
2956815Sralph  *
3056815Sralph  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
3156815Sralph  *  School of Computer Science
3256815Sralph  *  Carnegie Mellon University
3356815Sralph  *  Pittsburgh PA 15213-3890
3456815Sralph  *
3556815Sralph  * any improvements or extensions that they make and grant Carnegie the
3656815Sralph  * rights to redistribute these changes.
3756815Sralph  */
3856815Sralph /*
3956815Sralph  *  devGraphics.c --
4056815Sralph  *
4156815Sralph  *     	This file contains machine-dependent routines for the graphics device.
4256815Sralph  *
4356815Sralph  *	Copyright (C) 1989 Digital Equipment Corporation.
4456815Sralph  *	Permission to use, copy, modify, and distribute this software and
4556815Sralph  *	its documentation for any purpose and without fee is hereby granted,
4656815Sralph  *	provided that the above copyright notice appears in all copies.
4756815Sralph  *	Digital Equipment Corporation makes no representations about the
4856815Sralph  *	suitability of this software for any purpose.  It is provided "as is"
4956815Sralph  *	without express or implied warranty.
5056815Sralph  *
5156815Sralph  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
5256815Sralph  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
5356815Sralph  */
5456815Sralph 
5556815Sralph #include <mfb.h>
5656815Sralph #if NMFB > 0
5756815Sralph #include <sys/param.h>
5856815Sralph #include <sys/time.h>
5956815Sralph #include <sys/kernel.h>
6056815Sralph #include <sys/ioctl.h>
6156815Sralph #include <sys/file.h>
6256815Sralph #include <sys/errno.h>
6356815Sralph #include <sys/proc.h>
6456815Sralph #include <sys/mman.h>
6556815Sralph 
6656815Sralph #include <vm/vm.h>
6756815Sralph 
6856815Sralph #include <machine/machConst.h>
6956815Sralph #include <machine/pmioctl.h>
7056815Sralph 
7156815Sralph #include <pmax/pmax/cons.h>
7256815Sralph #include <pmax/pmax/pmaxtype.h>
7356815Sralph 
7456815Sralph #include <pmax/dev/device.h>
7556815Sralph #include <pmax/dev/mfbreg.h>
7656815Sralph #include <pmax/dev/fbreg.h>
7756815Sralph 
7856815Sralph #include <dc.h>
7956815Sralph #include <dtop.h>
8056815Sralph #include <scc.h>
8156815Sralph 
8256815Sralph /*
8356815Sralph  * These need to be mapped into user space.
8456815Sralph  */
8556815Sralph struct fbuaccess mfbu;
8656815Sralph struct pmax_fb mfbfb;
8756815Sralph 
8856815Sralph /*
8956815Sralph  * Forward references.
9056815Sralph  */
9156815Sralph extern void fbScroll();
9256815Sralph 
9356815Sralph static void mfbScreenInit();
9456815Sralph static void mfbLoadCursor();
9556815Sralph static void mfbRestoreCursorColor();
9656815Sralph static void mfbCursorColor();
9756815Sralph void mfbPosCursor();
9856815Sralph static void mfbInitColorMap();
9956815Sralph static void mfbLoadColorMap();
10056815Sralph static void mfbConfigMouse(), mfbDeconfigMouse();
10156815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg();
10256815Sralph static void bt431_write_reg(), bt431_init();
10356815Sralph static u_char bt431_read_reg();
10456815Sralph 
10556815Sralph extern void fbKbdEvent(), fbMouseEvent(), fbMouseButtons();
10656815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons();
10756815Sralph #if NDC > 0
10856815Sralph extern void (*dcDivertXInput)();
10956815Sralph extern void (*dcMouseEvent)();
11056815Sralph extern void (*dcMouseButtons)();
11156815Sralph #endif
11256815Sralph #if NSCC > 0
11356815Sralph extern void (*sccDivertXInput)();
11456815Sralph extern void (*sccMouseEvent)();
11556815Sralph extern void (*sccMouseButtons)();
11656815Sralph #endif
11756815Sralph #if NDTOP > 0
11856815Sralph extern void (*dtopDivertXInput)();
11956815Sralph extern void (*dtopMouseEvent)();
12056815Sralph extern void (*dtopMouseButtons)();
12156815Sralph #endif
12256815Sralph extern int pmax_boardtype;
12356815Sralph extern u_short defCursor[32];
12456815Sralph extern struct consdev cn_tab;
12556815Sralph 
12656815Sralph int	mfbprobe();
12756815Sralph struct	driver mfbdriver = {
12856815Sralph 	"mfb", mfbprobe, 0, 0,
12956815Sralph };
13056815Sralph 
13156815Sralph #define	MFB_OFFSET_VRAM		0x200000	/* from module's base */
13256815Sralph #define MFB_OFFSET_BT431	0x180000	/* Bt431 registers */
13356815Sralph #define MFB_OFFSET_BT455	0x100000	/* Bt455 registers */
13456815Sralph #define MFB_OFFSET_IREQ		0x080000	/* Interrupt req. control */
13556815Sralph #define MFB_OFFSET_ROM		0x0		/* Diagnostic ROM */
13656815Sralph 
13756815Sralph /*
13856815Sralph  * Test to see if device is present.
13956815Sralph  * Return true if found and initialized ok.
14056815Sralph  */
14156815Sralph /*ARGSUSED*/
14256815Sralph mfbprobe(cp)
14356815Sralph 	register struct pmax_ctlr *cp;
14456815Sralph {
14556815Sralph 	register struct pmax_fb *fp = &mfbfb;
14656815Sralph 
14756815Sralph 	if (!fp->initialized && !mfbinit(cp->pmax_addr))
14856815Sralph 		return (0);
14956815Sralph 	printf("mfb0 (mono display)\n");
15056815Sralph 	return (1);
15156815Sralph }
15256815Sralph 
15356815Sralph /*ARGSUSED*/
15456815Sralph mfbopen(dev, flag)
15556815Sralph 	dev_t dev;
15656815Sralph 	int flag;
15756815Sralph {
15856815Sralph 	register struct pmax_fb *fp = &mfbfb;
15956815Sralph 	int s;
16056815Sralph 
16156815Sralph 	if (!fp->initialized)
16256815Sralph 		return (ENXIO);
16356815Sralph 	if (fp->GraphicsOpen)
16456815Sralph 		return (EBUSY);
16556815Sralph 
16656815Sralph 	fp->GraphicsOpen = 1;
167*58793Sralph 	mfbInitColorMap(1);
16856815Sralph 	/*
16956815Sralph 	 * Set up event queue for later
17056815Sralph 	 */
17156815Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
17256815Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
17356815Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
17456815Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
17556815Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
17656815Sralph 	mfbConfigMouse();
17756815Sralph 	return (0);
17856815Sralph }
17956815Sralph 
18056815Sralph /*ARGSUSED*/
18156815Sralph mfbclose(dev, flag)
18256815Sralph 	dev_t dev;
18356815Sralph 	int flag;
18456815Sralph {
18556815Sralph 	register struct pmax_fb *fp = &mfbfb;
18656815Sralph 	int s;
18756815Sralph 
18856815Sralph 	if (!fp->GraphicsOpen)
18956815Sralph 		return (EBADF);
19056815Sralph 
19156815Sralph 	fp->GraphicsOpen = 0;
192*58793Sralph 	mfbInitColorMap(0);
19356815Sralph 	mfbDeconfigMouse();
19456815Sralph 	mfbScreenInit();
19556815Sralph 	vmUserUnmap();
196*58793Sralph 	bzero((caddr_t)fp->fr_addr, 2048 * 1024);
19756815Sralph 	mfbPosCursor(fp->col * 8, fp->row * 15);
19856815Sralph 	return (0);
19956815Sralph }
20056815Sralph 
20156815Sralph /*ARGSUSED*/
20256815Sralph mfbioctl(dev, cmd, data, flag)
20356815Sralph 	dev_t dev;
20456815Sralph 	caddr_t data;
20556815Sralph {
20656815Sralph 	register struct pmax_fb *fp = &mfbfb;
20756815Sralph 	int s;
20856815Sralph 
20956815Sralph 	switch (cmd) {
21056815Sralph 	case QIOCGINFO:
21156815Sralph 	    {
21256815Sralph 		caddr_t addr;
21356815Sralph 		extern caddr_t vmUserMap();
21456815Sralph 
21556815Sralph 		/*
21656815Sralph 		 * Map the all the data the user needs access to into
21756815Sralph 		 * user space.
21856815Sralph 		 */
21956815Sralph 		addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu);
22056815Sralph 		if (addr == (caddr_t)0)
22156815Sralph 			goto mapError;
22256815Sralph 		*(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo;
22356815Sralph 		fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events;
22456815Sralph 		fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs;
22556815Sralph 		fp->fbu->scrInfo.planemask = (char *)0;
22656815Sralph 		/*
22756815Sralph 		 * Map the frame buffer into the user's address space.
22856815Sralph 		 */
229*58793Sralph 		addr = vmUserMap(2048 * 1024, (unsigned)fp->fr_addr);
23056815Sralph 		if (addr == (caddr_t)0)
23156815Sralph 			goto mapError;
23256815Sralph 		fp->fbu->scrInfo.bitmap = (char *)addr;
23356815Sralph 		break;
23456815Sralph 
23556815Sralph 	mapError:
23656815Sralph 		vmUserUnmap();
23756815Sralph 		printf("Cannot map shared data structures\n");
23856815Sralph 		return (EIO);
23956815Sralph 	    }
24056815Sralph 
24156815Sralph 	case QIOCPMSTATE:
24256815Sralph 		/*
24356815Sralph 		 * Set mouse state.
24456815Sralph 		 */
24556815Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
24656815Sralph 		mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
24756815Sralph 		break;
24856815Sralph 
24956815Sralph 	case QIOCINIT:
25056815Sralph 		/*
25156815Sralph 		 * Initialize the screen.
25256815Sralph 		 */
25356815Sralph 		mfbScreenInit();
25456815Sralph 		break;
25556815Sralph 
25656815Sralph 	case QIOCKPCMD:
25756815Sralph 	    {
25856815Sralph 		pmKpCmd *kpCmdPtr;
25956815Sralph 		unsigned char *cp;
26056815Sralph 
26156815Sralph 		kpCmdPtr = (pmKpCmd *)data;
26256815Sralph 		if (kpCmdPtr->nbytes == 0)
26356815Sralph 			kpCmdPtr->cmd |= 0x80;
26456815Sralph 		if (!fp->GraphicsOpen)
26556815Sralph 			kpCmdPtr->cmd |= 1;
26656815Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
26756815Sralph 		cp = &kpCmdPtr->par[0];
26856815Sralph 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
26956815Sralph 			if (kpCmdPtr->nbytes == 1)
27056815Sralph 				*cp |= 0x80;
27156815Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
27256815Sralph 		}
27356815Sralph 	    }
27456815Sralph 	    break;
27556815Sralph 
27656815Sralph 	case QIOCADDR:
27756815Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
27856815Sralph 		break;
27956815Sralph 
28056815Sralph 	case QIOWCURSOR:
28156815Sralph 		mfbLoadCursor((unsigned short *)data);
28256815Sralph 		break;
28356815Sralph 
28456815Sralph 	case QIOWCURSORCOLOR:
28556815Sralph 		mfbCursorColor((unsigned int *)data);
28656815Sralph 		break;
28756815Sralph 
28856815Sralph 	case QIOSETCMAP:
289*58793Sralph #ifdef notdef
29056815Sralph 		mfbLoadColorMap((ColorMap *)data);
291*58793Sralph #endif
29256815Sralph 		break;
29356815Sralph 
29456815Sralph 	case QIOKERNLOOP:
29556815Sralph 		mfbConfigMouse();
29656815Sralph 		break;
29756815Sralph 
29856815Sralph 	case QIOKERNUNLOOP:
29956815Sralph 		mfbDeconfigMouse();
30056815Sralph 		break;
30156815Sralph 
30256815Sralph 	case QIOVIDEOON:
30356815Sralph 		bt455_video_on();
30456815Sralph 		break;
30556815Sralph 
30656815Sralph 	case QIOVIDEOOFF:
30756815Sralph 		bt455_video_off();
30856815Sralph 		break;
30956815Sralph 
31056815Sralph 	default:
31156815Sralph 		printf("mfb0: Unknown ioctl command %x\n", cmd);
31256815Sralph 		return (EINVAL);
31356815Sralph 	}
31456815Sralph 	return (0);
31556815Sralph }
31656815Sralph 
31756815Sralph mfbselect(dev, flag, p)
31856815Sralph 	dev_t dev;
31956815Sralph 	int flag;
32056815Sralph 	struct proc *p;
32156815Sralph {
32256815Sralph 	struct pmax_fb *fp = &mfbfb;
32356815Sralph 
32456815Sralph 	switch (flag) {
32556815Sralph 	case FREAD:
32656815Sralph 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
32756815Sralph 			return (1);
32856815Sralph 		selrecord(p, &fp->selp);
32956815Sralph 		break;
33056815Sralph 	}
33156815Sralph 
33256815Sralph 	return (0);
33356815Sralph }
33456815Sralph 
33556815Sralph static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
33656815Sralph 
33756815Sralph /*
33856815Sralph  * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit
33956815Sralph  * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding
34056815Sralph  * registers for these two chips live in adjacent bytes of the shorts that
34156815Sralph  * are defined in bt431_regmap_t.
34256815Sralph  */
34356815Sralph static void
34456815Sralph mfbLoadCursor(cursor)
34556815Sralph 	u_short *cursor;
34656815Sralph {
34756815Sralph 	register int i, j, k, pos;
34856815Sralph 	register u_short ap, bp, out;
34956815Sralph 	register bt431_regmap_t *regs;
35056815Sralph 
351*58793Sralph 	regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
352*58793Sralph 		 MFB_OFFSET_BT431);
35356815Sralph 	/*
35456815Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
35556815Sralph 	 * for the pmax.
35656815Sralph 	 * XXX This will have to change when the X server knows that this
357*58793Sralph 	 * is not a pmax display. (ie. Not the Xcfbpmax server.)
35856815Sralph 	 */
35956815Sralph 	pos = 0;
36056815Sralph 	bt431_select_reg(regs, BT431_REG_CRAM_BASE);
36156815Sralph 	for (k = 0; k < 16; k++) {
36256815Sralph 		ap = *cursor;
36356815Sralph 		bp = *(cursor + 16);
36456815Sralph 		j = 0;
36556815Sralph 		while (j < 2) {
36656815Sralph 			out = 0;
36756815Sralph 			for (i = 0; i < 8; i++) {
368*58793Sralph 				out = (out << 1) | ((bp & 0x1) << 8) |
369*58793Sralph 					(ap & 0x1);
37056815Sralph 				ap >>= 1;
37156815Sralph 				bp >>= 1;
37256815Sralph 			}
37356815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, out);
37456815Sralph 			pos++;
37556815Sralph 			j++;
37656815Sralph 		}
37756815Sralph 		while (j < 8) {
37856815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, 0);
37956815Sralph 			pos++;
38056815Sralph 			j++;
38156815Sralph 		}
38256815Sralph 		cursor++;
38356815Sralph 	}
38456815Sralph 	while (pos < 512) {
38556815Sralph 		BT431_WRITE_CMAP_AUTOI(regs, 0);
38656815Sralph 		pos++;
38756815Sralph 	}
38856815Sralph }
38956815Sralph 
39056815Sralph /*
39156815Sralph  * Initialization
39256815Sralph  */
39356815Sralph int
39456815Sralph mfbinit(cp)
39556815Sralph 	char *cp;
39656815Sralph {
39756815Sralph 	register struct pmax_fb *fp = &mfbfb;
39856815Sralph 
39956815Sralph 	/* check for no frame buffer */
40056815Sralph 	if (badaddr(cp, 4))
40156815Sralph 		return (0);
40256815Sralph 
403*58793Sralph 	fp->isMono = 0;
404*58793Sralph 	fp->fr_addr = cp + MFB_OFFSET_VRAM;
405*58793Sralph 	fp->fr_chipaddr = cp;
40657234Sralph 	/*
40757234Sralph 	 * Must be in Uncached space or the Xserver sees a stale version of
40857234Sralph 	 * the event queue and acts totally wacko. I don't understand this,
40957234Sralph 	 * since the R3000 uses a physical address cache?
41057234Sralph 	 */
41157234Sralph 	fp->fbu = (struct fbuaccess *)
41257234Sralph 		MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu));
41356815Sralph 	fp->posCursor = mfbPosCursor;
41457234Sralph 	if (tb_kbdmouseconfig(fp))
41556815Sralph 		return (0);
41656815Sralph 
41756815Sralph 	/*
41856815Sralph 	 * Initialize the screen.
41956815Sralph 	 */
420*58793Sralph 	bt431_init(fp->fr_chipaddr + MFB_OFFSET_BT431);
42156815Sralph 
42256815Sralph 	/*
42356815Sralph 	 * Initialize screen info.
42456815Sralph 	 */
42556815Sralph 	fp->fbu->scrInfo.max_row = 67;
42656815Sralph 	fp->fbu->scrInfo.max_col = 80;
42756815Sralph 	fp->fbu->scrInfo.max_x = 1280;
42856815Sralph 	fp->fbu->scrInfo.max_y = 1024;
42956815Sralph 	fp->fbu->scrInfo.max_cur_x = 1279;
43056815Sralph 	fp->fbu->scrInfo.max_cur_y = 1023;
43156815Sralph 	fp->fbu->scrInfo.version = 11;
43256815Sralph 	fp->fbu->scrInfo.mthreshold = 4;
43356815Sralph 	fp->fbu->scrInfo.mscale = 2;
43456815Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
43556815Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
43656815Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
43756815Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
43856815Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
43956815Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
44056815Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
44156815Sralph 
44256815Sralph 	/*
44356815Sralph 	 * Initialize the color map, the screen, and the mouse.
44456815Sralph 	 */
445*58793Sralph 	mfbInitColorMap(0);
44656815Sralph 	mfbScreenInit();
44756815Sralph 	fbScroll(fp);
44856815Sralph 
44956815Sralph 	fp->initialized = 1;
45056815Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
45156815Sralph 		cn_tab.cn_fb = fp;
45256815Sralph 	return (1);
45356815Sralph }
45456815Sralph 
45556815Sralph /*
45656815Sralph  * ----------------------------------------------------------------------------
45756815Sralph  *
45856815Sralph  * mfbScreenInit --
45956815Sralph  *
46056815Sralph  *	Initialize the screen.
46156815Sralph  *
46256815Sralph  * Results:
46356815Sralph  *	None.
46456815Sralph  *
46556815Sralph  * Side effects:
46656815Sralph  *	The screen is initialized.
46756815Sralph  *
46856815Sralph  * ----------------------------------------------------------------------------
46956815Sralph  */
47056815Sralph static void
47156815Sralph mfbScreenInit()
47256815Sralph {
47356815Sralph 	register struct pmax_fb *fp = &mfbfb;
47456815Sralph 
47556815Sralph 	/*
47656815Sralph 	 * Home the cursor.
47756815Sralph 	 * We want an LSI terminal emulation.  We want the graphics
47856815Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
47956815Sralph 	 */
48056815Sralph 	fp->row = 66;
48156815Sralph 	fp->col = 0;
48256815Sralph 
48356815Sralph 	/*
48456815Sralph 	 * Load the cursor with the default values
48556815Sralph 	 *
48656815Sralph 	 */
48756815Sralph 	mfbLoadCursor(defCursor);
48856815Sralph }
48956815Sralph 
49056815Sralph /*
49156815Sralph  * ----------------------------------------------------------------------------
49256815Sralph  *
49356815Sralph  * RestoreCursorColor --
49456815Sralph  *
49556815Sralph  *	Routine to restore the color of the cursor.
49656815Sralph  *
49756815Sralph  * Results:
49856815Sralph  *	None.
49956815Sralph  *
50056815Sralph  * Side effects:
50156815Sralph  *	None.
50256815Sralph  *
50356815Sralph  * ----------------------------------------------------------------------------
50456815Sralph  */
50556815Sralph static void
50656815Sralph mfbRestoreCursorColor()
50756815Sralph {
508*58793Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
509*58793Sralph 		MFB_OFFSET_BT455);
51056815Sralph 	ColorMap cm;
511*58793Sralph 	u_char fg;
51256815Sralph 
513*58793Sralph 	if (cursor_RGB[0] || cursor_RGB[1] || cursor_RGB[2])
514*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
515*58793Sralph 	else
516*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
51756815Sralph 	cm.index = 8;
51856815Sralph 	mfbLoadColorMap(&cm);
51956815Sralph 	cm.index = 9;
52056815Sralph 	mfbLoadColorMap(&cm);
52156815Sralph 
522*58793Sralph 	if (cursor_RGB[3] || cursor_RGB[4] || cursor_RGB[5])
523*58793Sralph 		fg = 0xf;
524*58793Sralph 	else
525*58793Sralph 		fg = 0;
526*58793Sralph 	regs->addr_ovly = fg;
52756815Sralph 	MachEmptyWriteBuffer();
528*58793Sralph 	regs->addr_ovly = fg;
52956815Sralph 	MachEmptyWriteBuffer();
530*58793Sralph 	regs->addr_ovly = fg;
53156815Sralph 	MachEmptyWriteBuffer();
53256815Sralph }
53356815Sralph 
53456815Sralph /*
53556815Sralph  * ----------------------------------------------------------------------------
53656815Sralph  *
53756815Sralph  * CursorColor --
53856815Sralph  *
53956815Sralph  *	Set the color of the cursor.
54056815Sralph  *
54156815Sralph  * Results:
54256815Sralph  *	None.
54356815Sralph  *
54456815Sralph  * Side effects:
54556815Sralph  *	None.
54656815Sralph  *
54756815Sralph  * ----------------------------------------------------------------------------
54856815Sralph  */
54956815Sralph static void
55056815Sralph mfbCursorColor(color)
55156815Sralph 	unsigned int color[];
55256815Sralph {
55356815Sralph 	register int i, j;
55456815Sralph 
55556815Sralph 	for (i = 0; i < 6; i++)
55656815Sralph 		cursor_RGB[i] = (u_char)(color[i] >> 8);
55756815Sralph 
55856815Sralph 	mfbRestoreCursorColor();
55956815Sralph }
56056815Sralph 
56156815Sralph /*
56256815Sralph  *----------------------------------------------------------------------
56356815Sralph  *
56456815Sralph  * PosCursor --
56556815Sralph  *
56656815Sralph  *	Postion the cursor.
56756815Sralph  *
56856815Sralph  * Results:
56956815Sralph  *	None.
57056815Sralph  *
57156815Sralph  * Side effects:
57256815Sralph  *	None.
57356815Sralph  *
57456815Sralph  *----------------------------------------------------------------------
57556815Sralph  */
57656815Sralph void
57756815Sralph mfbPosCursor(x, y)
57856815Sralph 	register int x, y;
57956815Sralph {
580*58793Sralph 	bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
581*58793Sralph 		 MFB_OFFSET_BT431);
58256815Sralph 	register struct pmax_fb *fp = &mfbfb;
58356815Sralph 
58456815Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
58556815Sralph 		y = fp->fbu->scrInfo.max_cur_y;
58656815Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
58756815Sralph 		x = fp->fbu->scrInfo.max_cur_x;
58856815Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
58956815Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
59056815Sralph 
59156815Sralph #define lo(v)	((v)&0xff)
59256815Sralph #define hi(v)	(((v)&0xf00)>>8)
59356815Sralph 
59456815Sralph 	/*
59556815Sralph 	 * Cx = x + D + H - P
59656815Sralph 	 *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
59756815Sralph 	 *  D = pixel skew between outdata and external data
59856815Sralph 	 *  H = pixels between HSYNCH falling and active video
59956815Sralph 	 *
60056815Sralph 	 * Cy = y + V - 32
60156815Sralph 	 *  V = scanlines between HSYNCH falling, two or more
60256815Sralph 	 *	clocks after VSYNCH falling, and active video
60356815Sralph 	 */
60456815Sralph 
605*58793Sralph 	bt431_write_reg(regs, BT431_REG_CXLO, lo(x + 360));
60656815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(x + 360));
60756815Sralph 	BT431_WRITE_REG_AUTOI(regs, lo(y + 36));
60856815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(y + 36));
60956815Sralph }
61056815Sralph 
61156815Sralph /*
61256815Sralph  * ----------------------------------------------------------------------------
61356815Sralph  *
61456815Sralph  * InitColorMap --
61556815Sralph  *
61656815Sralph  *	Initialize the color map.
61756815Sralph  *
61856815Sralph  * Results:
61956815Sralph  *	None.
62056815Sralph  *
62156815Sralph  * Side effects:
62256815Sralph  *	The colormap is initialized appropriately.
62356815Sralph  *
62456815Sralph  * ----------------------------------------------------------------------------
62556815Sralph  */
62656815Sralph static void
627*58793Sralph mfbInitColorMap(blackpix)
628*58793Sralph 	int blackpix;
62956815Sralph {
63056815Sralph 	ColorMap cm;
63156815Sralph 	register int i;
63256815Sralph 
63356815Sralph 	cm.index = 0;
634*58793Sralph 	if (blackpix)
635*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
636*58793Sralph 	else
637*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
63856815Sralph 	mfbLoadColorMap(&cm);
639*58793Sralph 	if (blackpix)
640*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
641*58793Sralph 	else
642*58793Sralph 		cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
64356815Sralph 	for (i = 1; i < 16; i++) {
64456815Sralph 		cm.index = i;
64556815Sralph 		mfbLoadColorMap(&cm);
64656815Sralph 	}
64756815Sralph 
64856815Sralph 	for (i = 0; i < 3; i++) {
649*58793Sralph 		cursor_RGB[i] = 0;
65056815Sralph 		cursor_RGB[i + 3] = 0xff;
65156815Sralph 	}
65256815Sralph 	mfbRestoreCursorColor();
65356815Sralph }
65456815Sralph 
65556815Sralph /*
65656815Sralph  * ----------------------------------------------------------------------------
65756815Sralph  *
65856815Sralph  * LoadColorMap --
65956815Sralph  *
66056815Sralph  *	Load the color map.
66156815Sralph  *
66256815Sralph  * Results:
66356815Sralph  *	None.
66456815Sralph  *
66556815Sralph  * Side effects:
66656815Sralph  *	The color map is loaded.
66756815Sralph  *
66856815Sralph  * ----------------------------------------------------------------------------
66956815Sralph  */
67056815Sralph static void
67156815Sralph mfbLoadColorMap(ptr)
67256815Sralph 	ColorMap *ptr;
67356815Sralph {
674*58793Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
675*58793Sralph 		 MFB_OFFSET_BT455);
67656815Sralph 
67756815Sralph 	if (ptr->index > 15)
67856815Sralph 		return;
67956815Sralph 
68056815Sralph 	BT455_SELECT_ENTRY(regs, ptr->index);
68156815Sralph 	regs->addr_cmap_data = ptr->Entry.red >> 12;
68256815Sralph 	MachEmptyWriteBuffer();
68356815Sralph 	regs->addr_cmap_data = ptr->Entry.green >> 12;
68456815Sralph 	MachEmptyWriteBuffer();
68556815Sralph 	regs->addr_cmap_data = ptr->Entry.blue >> 12;
68656815Sralph 	MachEmptyWriteBuffer();
68756815Sralph }
68856815Sralph 
68956815Sralph /*
69056815Sralph  * Video on/off state.
69156815Sralph  */
69256815Sralph static struct vstate {
69356815Sralph 	u_char	color0[6];	/* saved color map entry zero */
69456815Sralph 	u_char	off;		/* TRUE if display is off */
695*58793Sralph 	u_char	cursor[6];	/* saved cursor color */
69656815Sralph } vstate;
69756815Sralph 
69856815Sralph /*
69956815Sralph  * ----------------------------------------------------------------------------
70056815Sralph  *
70156815Sralph  * bt455_video_on
70256815Sralph  *
70356815Sralph  *	Enable the video display.
70456815Sralph  *
70556815Sralph  * Results:
70656815Sralph  *	None.
70756815Sralph  *
70856815Sralph  * Side effects:
70956815Sralph  *	The display is enabled.
71056815Sralph  *
71156815Sralph  * ----------------------------------------------------------------------------
71256815Sralph  */
71356815Sralph static void
71456815Sralph bt455_video_on()
71556815Sralph {
716*58793Sralph 	register int i;
717*58793Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
718*58793Sralph 		 MFB_OFFSET_BT455);
71956815Sralph 
72056815Sralph 	if (!vstate.off)
72156815Sralph 		return;
72256815Sralph 
72356815Sralph 	/* restore old color map entry zero */
72456815Sralph 	BT455_SELECT_ENTRY(regs, 0);
725*58793Sralph 	for (i = 0; i < 6; i++) {
726*58793Sralph 		regs->addr_cmap_data = vstate.color0[i];
727*58793Sralph 		MachEmptyWriteBuffer();
728*58793Sralph 		cursor_RGB[i] = vstate.cursor[i];
729*58793Sralph 	}
730*58793Sralph 	mfbRestoreCursorColor();
73156815Sralph 	vstate.off = 0;
73256815Sralph }
73356815Sralph 
73456815Sralph /*
73556815Sralph  * ----------------------------------------------------------------------------
73656815Sralph  *
73756815Sralph  * bt455_video_off
73856815Sralph  *
73956815Sralph  *	Disable the video display.
74056815Sralph  *
74156815Sralph  * Results:
74256815Sralph  *	None.
74356815Sralph  *
74456815Sralph  * Side effects:
74556815Sralph  *	The display is disabled.
74656815Sralph  *
74756815Sralph  * ----------------------------------------------------------------------------
74856815Sralph  */
74956815Sralph static void
75056815Sralph bt455_video_off()
75156815Sralph {
752*58793Sralph 	register int i;
753*58793Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
754*58793Sralph 		 MFB_OFFSET_BT455);
75556815Sralph 	ColorMap cm;
75656815Sralph 
75756815Sralph 	if (vstate.off)
75856815Sralph 		return;
75956815Sralph 
76056815Sralph 	/* save old color map entry zero */
76156815Sralph 	BT455_SELECT_ENTRY(regs, 0);
762*58793Sralph 	for (i = 0; i < 6; i++) {
763*58793Sralph 		vstate.color0[i] = regs->addr_cmap_data;
764*58793Sralph 		vstate.cursor[i] = cursor_RGB[i];
765*58793Sralph 		cursor_RGB[i] = 0;
766*58793Sralph 	}
76756815Sralph 
76856815Sralph 	/* set color map entry zero to zero */
76956815Sralph 	cm.index = 0;
77056815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
77156815Sralph 	mfbLoadColorMap(&cm);
77256815Sralph 	cm.index = 1;
77356815Sralph 	mfbLoadColorMap(&cm);
77456815Sralph 
775*58793Sralph 	mfbRestoreCursorColor();
77656815Sralph 	vstate.off = 1;
77756815Sralph }
77856815Sralph 
77956815Sralph /*
78056815Sralph  * mfb keyboard and mouse input. Just punt to the generic ones in fb.c
78156815Sralph  */
78256815Sralph void
78356815Sralph mfbKbdEvent(ch)
78456815Sralph 	int ch;
78556815Sralph {
78656815Sralph 	fbKbdEvent(ch, &mfbfb);
78756815Sralph }
78856815Sralph 
78956815Sralph void
79056815Sralph mfbMouseEvent(newRepPtr)
79156815Sralph 	MouseReport *newRepPtr;
79256815Sralph {
79356815Sralph 	fbMouseEvent(newRepPtr, &mfbfb);
79456815Sralph }
79556815Sralph 
79656815Sralph void
79756815Sralph mfbMouseButtons(newRepPtr)
79856815Sralph 	MouseReport *newRepPtr;
79956815Sralph {
80056815Sralph 	fbMouseButtons(newRepPtr, &mfbfb);
80156815Sralph }
80256815Sralph 
80356815Sralph /*
80456815Sralph  * Configure the mouse and keyboard based on machine type
80556815Sralph  */
80656815Sralph static void
80756815Sralph mfbConfigMouse()
80856815Sralph {
80956815Sralph 	int s;
81056815Sralph 
81156815Sralph 	s = spltty();
81256815Sralph 	switch (pmax_boardtype) {
81356815Sralph #if NDC > 0
81456815Sralph 	case DS_3MAX:
81556815Sralph 		dcDivertXInput = mfbKbdEvent;
81656815Sralph 		dcMouseEvent = mfbMouseEvent;
81756815Sralph 		dcMouseButtons = mfbMouseButtons;
81856815Sralph 		break;
81956815Sralph #endif
82056815Sralph #if NSCC > 1
82156815Sralph 	case DS_3MIN:
82256815Sralph 		sccDivertXInput = mfbKbdEvent;
82356815Sralph 		sccMouseEvent = mfbMouseEvent;
82456815Sralph 		sccMouseButtons = mfbMouseButtons;
82556815Sralph 		break;
82656815Sralph #endif
82756815Sralph #if NDTOP > 0
82856815Sralph 	case DS_MAXINE:
82956815Sralph 		dtopDivertXInput = mfbKbdEvent;
83056815Sralph 		dtopMouseEvent = mfbMouseEvent;
83156815Sralph 		dtopMouseButtons = mfbMouseButtons;
83256815Sralph 		break;
83356815Sralph #endif
83456815Sralph 	default:
83556815Sralph 		printf("Can't configure mouse/keyboard\n");
83656815Sralph 	};
83756815Sralph 	splx(s);
83856815Sralph }
83956815Sralph 
84056815Sralph /*
84156815Sralph  * and deconfigure them
84256815Sralph  */
84356815Sralph static void
84456815Sralph mfbDeconfigMouse()
84556815Sralph {
84656815Sralph 	int s;
84756815Sralph 
84856815Sralph 	s = spltty();
84956815Sralph 	switch (pmax_boardtype) {
85056815Sralph #if NDC > 0
85156815Sralph 	case DS_3MAX:
85256815Sralph 		dcDivertXInput = (void (*)())0;
85356815Sralph 		dcMouseEvent = (void (*)())0;
85456815Sralph 		dcMouseButtons = (void (*)())0;
85556815Sralph 		break;
85656815Sralph #endif
85756815Sralph #if NSCC > 1
85856815Sralph 	case DS_3MIN:
85956815Sralph 		sccDivertXInput = (void (*)())0;
86056815Sralph 		sccMouseEvent = (void (*)())0;
86156815Sralph 		sccMouseButtons = (void (*)())0;
86256815Sralph 		break;
86356815Sralph #endif
86456815Sralph #if NDTOP > 0
86556815Sralph 	case DS_MAXINE:
86656815Sralph 		dtopDivertXInput = (void (*)())0;
86756815Sralph 		dtopMouseEvent = (void (*)())0;
86856815Sralph 		dtopMouseButtons = (void (*)())0;
86956815Sralph 		break;
87056815Sralph #endif
87156815Sralph 	default:
87256815Sralph 		printf("Can't deconfigure mouse/keyboard\n");
87356815Sralph 	};
87456815Sralph }
87556815Sralph 
87656815Sralph /*
87756815Sralph  * Generic register access
87856815Sralph  */
87956815Sralph static void
88056815Sralph bt431_select_reg(regs, regno)
88156815Sralph 	bt431_regmap_t *regs;
88256815Sralph {
88356815Sralph 	regs->addr_lo = SET_VALUE(regno & 0xff);
88456815Sralph 	regs->addr_hi = SET_VALUE((regno >> 8) & 0xff);
88556815Sralph 	MachEmptyWriteBuffer();
88656815Sralph }
88756815Sralph 
88856815Sralph static void
88956815Sralph bt431_write_reg(regs, regno, val)
89056815Sralph 	bt431_regmap_t *regs;
89156815Sralph {
89256815Sralph 	bt431_select_reg(regs, regno);
89356815Sralph 	regs->addr_reg = SET_VALUE(val);
89456815Sralph 	MachEmptyWriteBuffer();
89556815Sralph }
89656815Sralph 
89756815Sralph static u_char
89856815Sralph bt431_read_reg(regs, regno)
89956815Sralph 	bt431_regmap_t *regs;
90056815Sralph {
90156815Sralph 	bt431_select_reg(regs, regno);
90256815Sralph 	return (GET_VALUE(regs->addr_reg));
90356815Sralph }
90456815Sralph 
90556815Sralph static void
90656815Sralph bt431_init(regs)
90756815Sralph 	bt431_regmap_t *regs;
90856815Sralph {
90956815Sralph 	register int i;
91056815Sralph 
91156815Sralph 	/* use 4:1 input mux */
91256815Sralph 	bt431_write_reg(regs, BT431_REG_CMD,
91356815Sralph 			 BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS|
91456815Sralph 			 BT431_CMD_4_1_MUX|BT431_CMD_THICK_1);
91556815Sralph 
91656815Sralph 	/* home cursor */
91756815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91856815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91956815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92056815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92156815Sralph 
92256815Sralph 	/* no crosshair window */
92356815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92456815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92556815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92656815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92756815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92856815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92956815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
93056815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
93156815Sralph }
93256815Sralph #endif /* NMFB */
933