xref: /csrg-svn/sys/pmax/dev/mfb.c (revision 57234)
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*57234Sralph  *	@(#)mfb.c	7.2 (Berkeley) 12/20/92
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;
16756815Sralph 	mfbInitColorMap();
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;
19256815Sralph 	mfbInitColorMap();
19356815Sralph 	mfbDeconfigMouse();
19456815Sralph 	mfbScreenInit();
19556815Sralph 	vmUserUnmap();
19656815Sralph 	bzero((caddr_t)fp->fr_addr, 256 * 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 		 */
22956815Sralph 		addr = vmUserMap(256 * 1024,
23056815Sralph 			(unsigned)(fp->fr_addr + MFB_OFFSET_VRAM));
23156815Sralph 		if (addr == (caddr_t)0)
23256815Sralph 			goto mapError;
23356815Sralph 		fp->fbu->scrInfo.bitmap = (char *)addr;
23456815Sralph 		break;
23556815Sralph 
23656815Sralph 	mapError:
23756815Sralph 		vmUserUnmap();
23856815Sralph 		printf("Cannot map shared data structures\n");
23956815Sralph 		return (EIO);
24056815Sralph 	    }
24156815Sralph 
24256815Sralph 	case QIOCPMSTATE:
24356815Sralph 		/*
24456815Sralph 		 * Set mouse state.
24556815Sralph 		 */
24656815Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
24756815Sralph 		mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
24856815Sralph 		break;
24956815Sralph 
25056815Sralph 	case QIOCINIT:
25156815Sralph 		/*
25256815Sralph 		 * Initialize the screen.
25356815Sralph 		 */
25456815Sralph 		mfbScreenInit();
25556815Sralph 		break;
25656815Sralph 
25756815Sralph 	case QIOCKPCMD:
25856815Sralph 	    {
25956815Sralph 		pmKpCmd *kpCmdPtr;
26056815Sralph 		unsigned char *cp;
26156815Sralph 
26256815Sralph 		kpCmdPtr = (pmKpCmd *)data;
26356815Sralph 		if (kpCmdPtr->nbytes == 0)
26456815Sralph 			kpCmdPtr->cmd |= 0x80;
26556815Sralph 		if (!fp->GraphicsOpen)
26656815Sralph 			kpCmdPtr->cmd |= 1;
26756815Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
26856815Sralph 		cp = &kpCmdPtr->par[0];
26956815Sralph 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
27056815Sralph 			if (kpCmdPtr->nbytes == 1)
27156815Sralph 				*cp |= 0x80;
27256815Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
27356815Sralph 		}
27456815Sralph 	    }
27556815Sralph 	    break;
27656815Sralph 
27756815Sralph 	case QIOCADDR:
27856815Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
27956815Sralph 		break;
28056815Sralph 
28156815Sralph 	case QIOWCURSOR:
28256815Sralph 		mfbLoadCursor((unsigned short *)data);
28356815Sralph 		break;
28456815Sralph 
28556815Sralph 	case QIOWCURSORCOLOR:
28656815Sralph 		mfbCursorColor((unsigned int *)data);
28756815Sralph 		break;
28856815Sralph 
28956815Sralph 	case QIOSETCMAP:
29056815Sralph 		mfbLoadColorMap((ColorMap *)data);
29156815Sralph 		break;
29256815Sralph 
29356815Sralph 	case QIOKERNLOOP:
29456815Sralph 		mfbConfigMouse();
29556815Sralph 		break;
29656815Sralph 
29756815Sralph 	case QIOKERNUNLOOP:
29856815Sralph 		mfbDeconfigMouse();
29956815Sralph 		break;
30056815Sralph 
30156815Sralph 	case QIOVIDEOON:
30256815Sralph 		mfbRestoreCursorColor();
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 
35156815Sralph 	regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431);
35256815Sralph 	/*
35356815Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
35456815Sralph 	 * for the pmax.
35556815Sralph 	 * XXX This will have to change when the X server knows that this
35656815Sralph 	 * is not a pmax display.
35756815Sralph 	 */
35856815Sralph 	pos = 0;
35956815Sralph 	bt431_select_reg(regs, BT431_REG_CRAM_BASE);
36056815Sralph 	for (k = 0; k < 16; k++) {
36156815Sralph 		ap = *cursor;
36256815Sralph 		bp = *(cursor + 16);
36356815Sralph 		j = 0;
36456815Sralph 		while (j < 2) {
36556815Sralph 			out = 0;
36656815Sralph 			for (i = 0; i < 8; i++) {
367*57234Sralph #ifdef CURSOR_EL
36856815Sralph 				out = (out << 1) | ((ap & 0x1) << 8) |
36956815Sralph 					(bp & 0x1);
370*57234Sralph #else
371*57234Sralph 				out = ((out >> 1) & 0x7f7f) |
372*57234Sralph 					((ap & 0x1) << 15) |
373*57234Sralph 					((bp & 0x1) << 7);
374*57234Sralph #endif
37556815Sralph 				ap >>= 1;
37656815Sralph 				bp >>= 1;
37756815Sralph 			}
37856815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, out);
37956815Sralph 			pos++;
38056815Sralph 			j++;
38156815Sralph 		}
38256815Sralph 		while (j < 8) {
38356815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, 0);
38456815Sralph 			pos++;
38556815Sralph 			j++;
38656815Sralph 		}
38756815Sralph 		cursor++;
38856815Sralph 	}
38956815Sralph 	while (pos < 512) {
39056815Sralph 		BT431_WRITE_CMAP_AUTOI(regs, 0);
39156815Sralph 		pos++;
39256815Sralph 	}
39356815Sralph }
39456815Sralph 
39556815Sralph /*
39656815Sralph  * Initialization
39756815Sralph  */
39856815Sralph int
39956815Sralph mfbinit(cp)
40056815Sralph 	char *cp;
40156815Sralph {
40256815Sralph 	register struct pmax_fb *fp = &mfbfb;
40356815Sralph 
40456815Sralph 	/* check for no frame buffer */
40556815Sralph 	if (badaddr(cp, 4))
40656815Sralph 		return (0);
40756815Sralph 
40856815Sralph 	fp->isMono = 1;
40956815Sralph 	fp->fr_addr = (char *)cp;
410*57234Sralph 	/*
411*57234Sralph 	 * Must be in Uncached space or the Xserver sees a stale version of
412*57234Sralph 	 * the event queue and acts totally wacko. I don't understand this,
413*57234Sralph 	 * since the R3000 uses a physical address cache?
414*57234Sralph 	 */
415*57234Sralph 	fp->fbu = (struct fbuaccess *)
416*57234Sralph 		MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu));
41756815Sralph 	fp->posCursor = mfbPosCursor;
418*57234Sralph 	if (tb_kbdmouseconfig(fp))
41956815Sralph 		return (0);
42056815Sralph 
42156815Sralph 	/*
42256815Sralph 	 * Initialize the screen.
42356815Sralph 	 */
42456815Sralph 	bt431_init(fp->fr_addr + MFB_OFFSET_BT431);
42556815Sralph 
42656815Sralph 	/*
42756815Sralph 	 * Initialize screen info.
42856815Sralph 	 */
42956815Sralph 	fp->fbu->scrInfo.max_row = 67;
43056815Sralph 	fp->fbu->scrInfo.max_col = 80;
43156815Sralph 	fp->fbu->scrInfo.max_x = 1280;
43256815Sralph 	fp->fbu->scrInfo.max_y = 1024;
43356815Sralph 	fp->fbu->scrInfo.max_cur_x = 1279;
43456815Sralph 	fp->fbu->scrInfo.max_cur_y = 1023;
43556815Sralph 	fp->fbu->scrInfo.version = 11;
43656815Sralph 	fp->fbu->scrInfo.mthreshold = 4;
43756815Sralph 	fp->fbu->scrInfo.mscale = 2;
43856815Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
43956815Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
44056815Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
44156815Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
44256815Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
44356815Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
44456815Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
44556815Sralph 
44656815Sralph 	/*
44756815Sralph 	 * Initialize the color map, the screen, and the mouse.
44856815Sralph 	 */
44956815Sralph 	mfbInitColorMap();
45056815Sralph 	mfbScreenInit();
45156815Sralph 	fbScroll(fp);
45256815Sralph 
45356815Sralph 	fp->initialized = 1;
45456815Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
45556815Sralph 		cn_tab.cn_fb = fp;
45656815Sralph 	return (1);
45756815Sralph }
45856815Sralph 
45956815Sralph /*
46056815Sralph  * ----------------------------------------------------------------------------
46156815Sralph  *
46256815Sralph  * mfbScreenInit --
46356815Sralph  *
46456815Sralph  *	Initialize the screen.
46556815Sralph  *
46656815Sralph  * Results:
46756815Sralph  *	None.
46856815Sralph  *
46956815Sralph  * Side effects:
47056815Sralph  *	The screen is initialized.
47156815Sralph  *
47256815Sralph  * ----------------------------------------------------------------------------
47356815Sralph  */
47456815Sralph static void
47556815Sralph mfbScreenInit()
47656815Sralph {
47756815Sralph 	register struct pmax_fb *fp = &mfbfb;
47856815Sralph 
47956815Sralph 	/*
48056815Sralph 	 * Home the cursor.
48156815Sralph 	 * We want an LSI terminal emulation.  We want the graphics
48256815Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
48356815Sralph 	 */
48456815Sralph 	fp->row = 66;
48556815Sralph 	fp->col = 0;
48656815Sralph 
48756815Sralph 	/*
48856815Sralph 	 * Load the cursor with the default values
48956815Sralph 	 *
49056815Sralph 	 */
49156815Sralph 	mfbLoadCursor(defCursor);
49256815Sralph }
49356815Sralph 
49456815Sralph /*
49556815Sralph  * ----------------------------------------------------------------------------
49656815Sralph  *
49756815Sralph  * RestoreCursorColor --
49856815Sralph  *
49956815Sralph  *	Routine to restore the color of the cursor.
50056815Sralph  *
50156815Sralph  * Results:
50256815Sralph  *	None.
50356815Sralph  *
50456815Sralph  * Side effects:
50556815Sralph  *	None.
50656815Sralph  *
50756815Sralph  * ----------------------------------------------------------------------------
50856815Sralph  */
50956815Sralph static void
51056815Sralph mfbRestoreCursorColor()
51156815Sralph {
51256815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
51356815Sralph 	ColorMap cm;
51456815Sralph 	register int i;
51556815Sralph 
51656815Sralph 	cm.index = 8;
51756815Sralph 	cm.Entry.red = cursor_RGB[0] << 8;
51856815Sralph 	cm.Entry.green = cursor_RGB[1] << 8;
51956815Sralph 	cm.Entry.blue = cursor_RGB[2] << 8;
52056815Sralph 	mfbLoadColorMap(&cm);
52156815Sralph 	cm.index = 9;
52256815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
52356815Sralph 	mfbLoadColorMap(&cm);
52456815Sralph 
52556815Sralph 	regs->addr_ovly = cursor_RGB[3] >> 4;
52656815Sralph 	MachEmptyWriteBuffer();
52756815Sralph 	regs->addr_ovly = cursor_RGB[4] >> 4;
52856815Sralph 	MachEmptyWriteBuffer();
52956815Sralph 	regs->addr_ovly = cursor_RGB[5] >> 4;
53056815Sralph 	MachEmptyWriteBuffer();
53156815Sralph }
53256815Sralph 
53356815Sralph /*
53456815Sralph  * ----------------------------------------------------------------------------
53556815Sralph  *
53656815Sralph  * CursorColor --
53756815Sralph  *
53856815Sralph  *	Set the color of the cursor.
53956815Sralph  *
54056815Sralph  * Results:
54156815Sralph  *	None.
54256815Sralph  *
54356815Sralph  * Side effects:
54456815Sralph  *	None.
54556815Sralph  *
54656815Sralph  * ----------------------------------------------------------------------------
54756815Sralph  */
54856815Sralph static void
54956815Sralph mfbCursorColor(color)
55056815Sralph 	unsigned int color[];
55156815Sralph {
55256815Sralph 	register int i, j;
55356815Sralph 
55456815Sralph 	for (i = 0; i < 6; i++)
55556815Sralph 		cursor_RGB[i] = (u_char)(color[i] >> 8);
55656815Sralph 
55756815Sralph 	mfbRestoreCursorColor();
55856815Sralph }
55956815Sralph 
56056815Sralph /*
56156815Sralph  *----------------------------------------------------------------------
56256815Sralph  *
56356815Sralph  * PosCursor --
56456815Sralph  *
56556815Sralph  *	Postion the cursor.
56656815Sralph  *
56756815Sralph  * Results:
56856815Sralph  *	None.
56956815Sralph  *
57056815Sralph  * Side effects:
57156815Sralph  *	None.
57256815Sralph  *
57356815Sralph  *----------------------------------------------------------------------
57456815Sralph  */
57556815Sralph void
57656815Sralph mfbPosCursor(x, y)
57756815Sralph 	register int x, y;
57856815Sralph {
57956815Sralph 	bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431);
58056815Sralph 	register struct pmax_fb *fp = &mfbfb;
58156815Sralph 
58256815Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
58356815Sralph 		y = fp->fbu->scrInfo.max_cur_y;
58456815Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
58556815Sralph 		x = fp->fbu->scrInfo.max_cur_x;
58656815Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
58756815Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
58856815Sralph 
58956815Sralph #define lo(v)	((v)&0xff)
59056815Sralph #define hi(v)	(((v)&0xf00)>>8)
59156815Sralph 
59256815Sralph 	/*
59356815Sralph 	 * Cx = x + D + H - P
59456815Sralph 	 *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
59556815Sralph 	 *  D = pixel skew between outdata and external data
59656815Sralph 	 *  H = pixels between HSYNCH falling and active video
59756815Sralph 	 *
59856815Sralph 	 * Cy = y + V - 32
59956815Sralph 	 *  V = scanlines between HSYNCH falling, two or more
60056815Sralph 	 *	clocks after VSYNCH falling, and active video
60156815Sralph 	 */
60256815Sralph 
60356815Sralph 	bt431_write_reg(regs, lo(x + 360));
60456815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(x + 360));
60556815Sralph 	BT431_WRITE_REG_AUTOI(regs, lo(y + 36));
60656815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(y + 36));
60756815Sralph }
60856815Sralph 
60956815Sralph /*
61056815Sralph  * ----------------------------------------------------------------------------
61156815Sralph  *
61256815Sralph  * InitColorMap --
61356815Sralph  *
61456815Sralph  *	Initialize the color map.
61556815Sralph  *
61656815Sralph  * Results:
61756815Sralph  *	None.
61856815Sralph  *
61956815Sralph  * Side effects:
62056815Sralph  *	The colormap is initialized appropriately.
62156815Sralph  *
62256815Sralph  * ----------------------------------------------------------------------------
62356815Sralph  */
62456815Sralph static void
62556815Sralph mfbInitColorMap()
62656815Sralph {
62756815Sralph 	ColorMap cm;
62856815Sralph 	register int i;
62956815Sralph 
63056815Sralph 	cm.index = 0;
63156815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
63256815Sralph 	mfbLoadColorMap(&cm);
63356815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
63456815Sralph 	for (i = 1; i < 16; i++) {
63556815Sralph 		cm.index = i;
63656815Sralph 		mfbLoadColorMap(&cm);
63756815Sralph 	}
63856815Sralph 
63956815Sralph 	for (i = 0; i < 3; i++) {
64056815Sralph 		cursor_RGB[i] = 0x00;
64156815Sralph 		cursor_RGB[i + 3] = 0xff;
64256815Sralph 	}
64356815Sralph 	mfbRestoreCursorColor();
64456815Sralph }
64556815Sralph 
64656815Sralph /*
64756815Sralph  * ----------------------------------------------------------------------------
64856815Sralph  *
64956815Sralph  * LoadColorMap --
65056815Sralph  *
65156815Sralph  *	Load the color map.
65256815Sralph  *
65356815Sralph  * Results:
65456815Sralph  *	None.
65556815Sralph  *
65656815Sralph  * Side effects:
65756815Sralph  *	The color map is loaded.
65856815Sralph  *
65956815Sralph  * ----------------------------------------------------------------------------
66056815Sralph  */
66156815Sralph static void
66256815Sralph mfbLoadColorMap(ptr)
66356815Sralph 	ColorMap *ptr;
66456815Sralph {
66556815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
66656815Sralph 
66756815Sralph 	if (ptr->index > 15)
66856815Sralph 		return;
66956815Sralph 
67056815Sralph 	BT455_SELECT_ENTRY(regs, ptr->index);
67156815Sralph 	regs->addr_cmap_data = ptr->Entry.red >> 12;
67256815Sralph 	MachEmptyWriteBuffer();
67356815Sralph 	regs->addr_cmap_data = ptr->Entry.green >> 12;
67456815Sralph 	MachEmptyWriteBuffer();
67556815Sralph 	regs->addr_cmap_data = ptr->Entry.blue >> 12;
67656815Sralph 	MachEmptyWriteBuffer();
67756815Sralph }
67856815Sralph 
67956815Sralph /*
68056815Sralph  * Video on/off state.
68156815Sralph  */
68256815Sralph static struct vstate {
68356815Sralph 	u_char	color0[6];	/* saved color map entry zero */
68456815Sralph 	u_char	off;		/* TRUE if display is off */
68556815Sralph } vstate;
68656815Sralph 
68756815Sralph /*
68856815Sralph  * ----------------------------------------------------------------------------
68956815Sralph  *
69056815Sralph  * bt455_video_on
69156815Sralph  *
69256815Sralph  *	Enable the video display.
69356815Sralph  *
69456815Sralph  * Results:
69556815Sralph  *	None.
69656815Sralph  *
69756815Sralph  * Side effects:
69856815Sralph  *	The display is enabled.
69956815Sralph  *
70056815Sralph  * ----------------------------------------------------------------------------
70156815Sralph  */
70256815Sralph static void
70356815Sralph bt455_video_on()
70456815Sralph {
70556815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
70656815Sralph 
70756815Sralph 	if (!vstate.off)
70856815Sralph 		return;
70956815Sralph 
71056815Sralph 	/* restore old color map entry zero */
71156815Sralph 	BT455_SELECT_ENTRY(regs, 0);
71256815Sralph 	regs->addr_cmap_data = vstate.color0[0];
71356815Sralph 	MachEmptyWriteBuffer();
71456815Sralph 	regs->addr_cmap_data = vstate.color0[1];
71556815Sralph 	MachEmptyWriteBuffer();
71656815Sralph 	regs->addr_cmap_data = vstate.color0[2];
71756815Sralph 	MachEmptyWriteBuffer();
71856815Sralph 	regs->addr_cmap_data = vstate.color0[3];
71956815Sralph 	MachEmptyWriteBuffer();
72056815Sralph 	regs->addr_cmap_data = vstate.color0[4];
72156815Sralph 	MachEmptyWriteBuffer();
72256815Sralph 	regs->addr_cmap_data = vstate.color0[5];
72356815Sralph 	MachEmptyWriteBuffer();
72456815Sralph 
72556815Sralph 	vstate.off = 0;
72656815Sralph }
72756815Sralph 
72856815Sralph /*
72956815Sralph  * ----------------------------------------------------------------------------
73056815Sralph  *
73156815Sralph  * bt455_video_off
73256815Sralph  *
73356815Sralph  *	Disable the video display.
73456815Sralph  *
73556815Sralph  * Results:
73656815Sralph  *	None.
73756815Sralph  *
73856815Sralph  * Side effects:
73956815Sralph  *	The display is disabled.
74056815Sralph  *
74156815Sralph  * ----------------------------------------------------------------------------
74256815Sralph  */
74356815Sralph static void
74456815Sralph bt455_video_off()
74556815Sralph {
74656815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
74756815Sralph 	ColorMap cm;
74856815Sralph 
74956815Sralph 	if (vstate.off)
75056815Sralph 		return;
75156815Sralph 
75256815Sralph 	/* save old color map entry zero */
75356815Sralph 	BT455_SELECT_ENTRY(regs, 0);
75456815Sralph 	vstate.color0[0] = regs->addr_cmap_data;
75556815Sralph 	vstate.color0[1] = regs->addr_cmap_data;
75656815Sralph 	vstate.color0[2] = regs->addr_cmap_data;
75756815Sralph 	vstate.color0[3] = regs->addr_cmap_data;
75856815Sralph 	vstate.color0[4] = regs->addr_cmap_data;
75956815Sralph 	vstate.color0[5] = regs->addr_cmap_data;
76056815Sralph 
76156815Sralph 	/* set color map entry zero to zero */
76256815Sralph 	cm.index = 0;
76356815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
76456815Sralph 	mfbLoadColorMap(&cm);
76556815Sralph 	cm.index = 1;
76656815Sralph 	mfbLoadColorMap(&cm);
76756815Sralph 
76856815Sralph 	vstate.off = 1;
76956815Sralph }
77056815Sralph 
77156815Sralph /*
77256815Sralph  * mfb keyboard and mouse input. Just punt to the generic ones in fb.c
77356815Sralph  */
77456815Sralph void
77556815Sralph mfbKbdEvent(ch)
77656815Sralph 	int ch;
77756815Sralph {
77856815Sralph 	fbKbdEvent(ch, &mfbfb);
77956815Sralph }
78056815Sralph 
78156815Sralph void
78256815Sralph mfbMouseEvent(newRepPtr)
78356815Sralph 	MouseReport *newRepPtr;
78456815Sralph {
78556815Sralph 	fbMouseEvent(newRepPtr, &mfbfb);
78656815Sralph }
78756815Sralph 
78856815Sralph void
78956815Sralph mfbMouseButtons(newRepPtr)
79056815Sralph 	MouseReport *newRepPtr;
79156815Sralph {
79256815Sralph 	fbMouseButtons(newRepPtr, &mfbfb);
79356815Sralph }
79456815Sralph 
79556815Sralph /*
79656815Sralph  * Configure the mouse and keyboard based on machine type
79756815Sralph  */
79856815Sralph static void
79956815Sralph mfbConfigMouse()
80056815Sralph {
80156815Sralph 	int s;
80256815Sralph 
80356815Sralph 	s = spltty();
80456815Sralph 	switch (pmax_boardtype) {
80556815Sralph #if NDC > 0
80656815Sralph 	case DS_3MAX:
80756815Sralph 		dcDivertXInput = mfbKbdEvent;
80856815Sralph 		dcMouseEvent = mfbMouseEvent;
80956815Sralph 		dcMouseButtons = mfbMouseButtons;
81056815Sralph 		break;
81156815Sralph #endif
81256815Sralph #if NSCC > 1
81356815Sralph 	case DS_3MIN:
81456815Sralph 		sccDivertXInput = mfbKbdEvent;
81556815Sralph 		sccMouseEvent = mfbMouseEvent;
81656815Sralph 		sccMouseButtons = mfbMouseButtons;
81756815Sralph 		break;
81856815Sralph #endif
81956815Sralph #if NDTOP > 0
82056815Sralph 	case DS_MAXINE:
82156815Sralph 		dtopDivertXInput = mfbKbdEvent;
82256815Sralph 		dtopMouseEvent = mfbMouseEvent;
82356815Sralph 		dtopMouseButtons = mfbMouseButtons;
82456815Sralph 		break;
82556815Sralph #endif
82656815Sralph 	default:
82756815Sralph 		printf("Can't configure mouse/keyboard\n");
82856815Sralph 	};
82956815Sralph 	splx(s);
83056815Sralph }
83156815Sralph 
83256815Sralph /*
83356815Sralph  * and deconfigure them
83456815Sralph  */
83556815Sralph static void
83656815Sralph mfbDeconfigMouse()
83756815Sralph {
83856815Sralph 	int s;
83956815Sralph 
84056815Sralph 	s = spltty();
84156815Sralph 	switch (pmax_boardtype) {
84256815Sralph #if NDC > 0
84356815Sralph 	case DS_3MAX:
84456815Sralph 		dcDivertXInput = (void (*)())0;
84556815Sralph 		dcMouseEvent = (void (*)())0;
84656815Sralph 		dcMouseButtons = (void (*)())0;
84756815Sralph 		break;
84856815Sralph #endif
84956815Sralph #if NSCC > 1
85056815Sralph 	case DS_3MIN:
85156815Sralph 		sccDivertXInput = (void (*)())0;
85256815Sralph 		sccMouseEvent = (void (*)())0;
85356815Sralph 		sccMouseButtons = (void (*)())0;
85456815Sralph 		break;
85556815Sralph #endif
85656815Sralph #if NDTOP > 0
85756815Sralph 	case DS_MAXINE:
85856815Sralph 		dtopDivertXInput = (void (*)())0;
85956815Sralph 		dtopMouseEvent = (void (*)())0;
86056815Sralph 		dtopMouseButtons = (void (*)())0;
86156815Sralph 		break;
86256815Sralph #endif
86356815Sralph 	default:
86456815Sralph 		printf("Can't deconfigure mouse/keyboard\n");
86556815Sralph 	};
86656815Sralph }
86756815Sralph 
86856815Sralph /*
86956815Sralph  * Generic register access
87056815Sralph  */
87156815Sralph static void
87256815Sralph bt431_select_reg(regs, regno)
87356815Sralph 	bt431_regmap_t *regs;
87456815Sralph {
87556815Sralph 	regs->addr_lo = SET_VALUE(regno & 0xff);
87656815Sralph 	regs->addr_hi = SET_VALUE((regno >> 8) & 0xff);
87756815Sralph 	MachEmptyWriteBuffer();
87856815Sralph }
87956815Sralph 
88056815Sralph static void
88156815Sralph bt431_write_reg(regs, regno, val)
88256815Sralph 	bt431_regmap_t *regs;
88356815Sralph {
88456815Sralph 	bt431_select_reg(regs, regno);
88556815Sralph 	regs->addr_reg = SET_VALUE(val);
88656815Sralph 	MachEmptyWriteBuffer();
88756815Sralph }
88856815Sralph 
88956815Sralph static u_char
89056815Sralph bt431_read_reg(regs, regno)
89156815Sralph 	bt431_regmap_t *regs;
89256815Sralph {
89356815Sralph 	bt431_select_reg(regs, regno);
89456815Sralph 	return (GET_VALUE(regs->addr_reg));
89556815Sralph }
89656815Sralph 
89756815Sralph static void
89856815Sralph bt431_init(regs)
89956815Sralph 	bt431_regmap_t *regs;
90056815Sralph {
90156815Sralph 	register int i;
90256815Sralph 
90356815Sralph 	/* use 4:1 input mux */
90456815Sralph 	bt431_write_reg(regs, BT431_REG_CMD,
90556815Sralph 			 BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS|
90656815Sralph 			 BT431_CMD_4_1_MUX|BT431_CMD_THICK_1);
90756815Sralph 
90856815Sralph 	/* home cursor */
90956815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91056815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91156815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91256815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91356815Sralph 
91456815Sralph 	/* no crosshair window */
91556815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
91656815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
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 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92256815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
92356815Sralph }
92456815Sralph #endif /* NMFB */
925