xref: /csrg-svn/sys/pmax/dev/cfb.c (revision 63205)
152891Sbostic /*-
2*63205Sbostic  * Copyright (c) 1992, 1993
3*63205Sbostic  *	The Regents of the University of California.  All rights reserved.
452891Sbostic  *
552891Sbostic  * This code is derived from software contributed to Berkeley by
656819Sralph  * Ralph Campbell and Rick Macklem.
752891Sbostic  *
852891Sbostic  * %sccs.include.redist.c%
952891Sbostic  *
10*63205Sbostic  *	@(#)cfb.c	8.1 (Berkeley) 06/10/93
1152891Sbostic  */
1252891Sbostic 
1352891Sbostic /*
1452891Sbostic  *  devGraphics.c --
1552891Sbostic  *
1652891Sbostic  *     	This file contains machine-dependent routines for the graphics device.
1752891Sbostic  *
1852891Sbostic  *	Copyright (C) 1989 Digital Equipment Corporation.
1952891Sbostic  *	Permission to use, copy, modify, and distribute this software and
2052891Sbostic  *	its documentation for any purpose and without fee is hereby granted,
2152891Sbostic  *	provided that the above copyright notice appears in all copies.
2252891Sbostic  *	Digital Equipment Corporation makes no representations about the
2352891Sbostic  *	suitability of this software for any purpose.  It is provided "as is"
2452891Sbostic  *	without express or implied warranty.
2552891Sbostic  *
2652891Sbostic  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
2752891Sbostic  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
2852891Sbostic  */
2952891Sbostic /*
3052891Sbostic  * Mach Operating System
3152891Sbostic  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
3252891Sbostic  * All Rights Reserved.
3352891Sbostic  *
3452891Sbostic  * Permission to use, copy, modify and distribute this software and its
3552891Sbostic  * documentation is hereby granted, provided that both the copyright
3652891Sbostic  * notice and this permission notice appear in all copies of the
3752891Sbostic  * software, derivative works or modified versions, and any portions
3852891Sbostic  * thereof, and that both notices appear in supporting documentation.
3952891Sbostic  *
4052891Sbostic  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
4152891Sbostic  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
4252891Sbostic  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
4352891Sbostic  *
4452891Sbostic  * Carnegie Mellon requests users of this software to return to
4552891Sbostic  *
4652891Sbostic  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
4752891Sbostic  *  School of Computer Science
4852891Sbostic  *  Carnegie Mellon University
4952891Sbostic  *  Pittsburgh PA 15213-3890
5052891Sbostic  *
5152891Sbostic  * any improvements or extensions that they make and grant Carnegie the
5252891Sbostic  * rights to redistribute these changes.
5352891Sbostic  */
5452891Sbostic 
5556819Sralph #include <cfb.h>
5652891Sbostic #if NCFB > 0
5756522Sbostic #include <sys/param.h>
5856522Sbostic #include <sys/time.h>
5956522Sbostic #include <sys/kernel.h>
6056522Sbostic #include <sys/ioctl.h>
6156522Sbostic #include <sys/file.h>
6256522Sbostic #include <sys/errno.h>
6356522Sbostic #include <sys/proc.h>
6456522Sbostic #include <sys/mman.h>
6552891Sbostic 
6656522Sbostic #include <vm/vm.h>
6752891Sbostic 
6856522Sbostic #include <machine/machConst.h>
6956522Sbostic #include <machine/pmioctl.h>
7052891Sbostic 
7156819Sralph #include <pmax/pmax/maxine.h>
7256819Sralph #include <pmax/pmax/cons.h>
7356819Sralph #include <pmax/pmax/pmaxtype.h>
7456819Sralph 
7556525Sbostic #include <pmax/dev/device.h>
7656525Sbostic #include <pmax/dev/cfbreg.h>
7756819Sralph #include <pmax/dev/fbreg.h>
7856522Sbostic 
7956819Sralph #include <dc.h>
8056819Sralph #include <dtop.h>
8156819Sralph #include <scc.h>
8252891Sbostic 
8359070Sralph #define PMAX	/* enable /dev/pm compatibility */
8459070Sralph 
8552891Sbostic /*
8652891Sbostic  * These need to be mapped into user space.
8752891Sbostic  */
8856819Sralph struct fbuaccess cfbu;
8956819Sralph struct pmax_fb cfbfb;
9052891Sbostic 
9152891Sbostic /*
9252891Sbostic  * Forward references.
9352891Sbostic  */
9456819Sralph static void cfbScreenInit();
9556819Sralph static void cfbLoadCursor();
9656819Sralph static void cfbRestoreCursorColor();
9756819Sralph static void cfbCursorColor();
9856819Sralph void cfbPosCursor();
9956819Sralph static void cfbInitColorMap();
10056819Sralph static void cfbLoadColorMap();
10156819Sralph static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off();
10256819Sralph static void bt459_select_reg(), bt459_write_reg();
10356819Sralph static u_char bt459_read_reg();
10456819Sralph static void cfbConfigMouse(), cfbDeconfigMouse();
10552891Sbostic 
10656819Sralph void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons();
10756819Sralph #if NDC > 0
10852891Sbostic extern void (*dcDivertXInput)();
10952891Sbostic extern void (*dcMouseEvent)();
11052891Sbostic extern void (*dcMouseButtons)();
11156819Sralph #endif
11256819Sralph #if NSCC > 0
11356819Sralph extern void (*sccDivertXInput)();
11456819Sralph extern void (*sccMouseEvent)();
11556819Sralph extern void (*sccMouseButtons)();
11656819Sralph #endif
11756819Sralph #if NDTOP > 0
11856819Sralph extern void (*dtopDivertXInput)();
11956819Sralph extern void (*dtopMouseEvent)();
12056819Sralph extern void (*dtopMouseButtons)();
12156819Sralph #endif
12256819Sralph extern int pmax_boardtype;
12356819Sralph extern u_short defCursor[32];
12456819Sralph extern struct consdev cn_tab;
12552891Sbostic 
12652891Sbostic int	cfbprobe();
12752891Sbostic struct	driver cfbdriver = {
12852891Sbostic 	"cfb", cfbprobe, 0, 0,
12952891Sbostic };
13052891Sbostic 
13156819Sralph #define	CFB_OFFSET_VRAM		0x0		/* from module's base */
13256819Sralph #define CFB_OFFSET_BT459	0x200000	/* Bt459 registers */
13356819Sralph #define CFB_OFFSET_IREQ		0x300000	/* Interrupt req. control */
13456819Sralph #define CFB_OFFSET_ROM		0x380000	/* Diagnostic ROM */
13556819Sralph #define CFB_OFFSET_RESET	0x3c0000	/* Bt459 resets on writes */
13658974Sralph #define CFB_FB_SIZE		0x100000	/* frame buffer size */
13756819Sralph 
13852891Sbostic /*
13952891Sbostic  * Test to see if device is present.
14052891Sbostic  * Return true if found and initialized ok.
14152891Sbostic  */
14256819Sralph /*ARGSUSED*/
14352891Sbostic cfbprobe(cp)
14452891Sbostic 	register struct pmax_ctlr *cp;
14552891Sbostic {
14656819Sralph 	register struct pmax_fb *fp = &cfbfb;
14752891Sbostic 
14856819Sralph 	if (!fp->initialized && !cfbinit(cp->pmax_addr))
14956819Sralph 		return (0);
15056819Sralph 	printf("cfb0 (color display)\n");
15152891Sbostic 	return (1);
15252891Sbostic }
15352891Sbostic 
15452891Sbostic /*ARGSUSED*/
15552891Sbostic cfbopen(dev, flag)
15652891Sbostic 	dev_t dev;
15752891Sbostic 	int flag;
15852891Sbostic {
15956819Sralph 	register struct pmax_fb *fp = &cfbfb;
16056819Sralph 	int s;
16152891Sbostic 
16256819Sralph 	if (!fp->initialized)
16352891Sbostic 		return (ENXIO);
16456819Sralph 	if (fp->GraphicsOpen)
16552891Sbostic 		return (EBUSY);
16652891Sbostic 
16756819Sralph 	fp->GraphicsOpen = 1;
16856819Sralph 	cfbInitColorMap();
16952891Sbostic 	/*
17052891Sbostic 	 * Set up event queue for later
17152891Sbostic 	 */
17256819Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
17356819Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
17456819Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
17556819Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
17656819Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
17756819Sralph 	cfbConfigMouse();
17852891Sbostic 	return (0);
17952891Sbostic }
18052891Sbostic 
18152891Sbostic /*ARGSUSED*/
18252891Sbostic cfbclose(dev, flag)
18352891Sbostic 	dev_t dev;
18452891Sbostic 	int flag;
18552891Sbostic {
18656819Sralph 	register struct pmax_fb *fp = &cfbfb;
18752959Sralph 	int s;
18852891Sbostic 
18956819Sralph 	if (!fp->GraphicsOpen)
19052891Sbostic 		return (EBADF);
19152891Sbostic 
19256819Sralph 	fp->GraphicsOpen = 0;
19356819Sralph 	cfbInitColorMap();
19456819Sralph 	cfbDeconfigMouse();
19556819Sralph 	cfbScreenInit();
19656819Sralph 	bzero((caddr_t)fp->fr_addr, 1024 * 864);
19756819Sralph 	cfbPosCursor(fp->col * 8, fp->row * 15);
19852891Sbostic 	return (0);
19952891Sbostic }
20052891Sbostic 
20152891Sbostic /*ARGSUSED*/
20258974Sralph cfbioctl(dev, cmd, data, flag, p)
20352891Sbostic 	dev_t dev;
20452891Sbostic 	caddr_t data;
20558974Sralph 	struct proc *p;
20652891Sbostic {
20756819Sralph 	register struct pmax_fb *fp = &cfbfb;
20852959Sralph 	int s;
20952891Sbostic 
21052891Sbostic 	switch (cmd) {
21152891Sbostic 	case QIOCGINFO:
21258974Sralph 		return (fbmmap(fp, dev, data, p));
21352891Sbostic 
21452891Sbostic 	case QIOCPMSTATE:
21552891Sbostic 		/*
21652891Sbostic 		 * Set mouse state.
21752891Sbostic 		 */
21856819Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
21956819Sralph 		cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
22052891Sbostic 		break;
22152891Sbostic 
22252891Sbostic 	case QIOCINIT:
22352891Sbostic 		/*
22452891Sbostic 		 * Initialize the screen.
22552891Sbostic 		 */
22656819Sralph 		cfbScreenInit();
22752891Sbostic 		break;
22852891Sbostic 
22952891Sbostic 	case QIOCKPCMD:
23052891Sbostic 	    {
23152891Sbostic 		pmKpCmd *kpCmdPtr;
23252891Sbostic 		unsigned char *cp;
23352891Sbostic 
23452891Sbostic 		kpCmdPtr = (pmKpCmd *)data;
23552891Sbostic 		if (kpCmdPtr->nbytes == 0)
23652891Sbostic 			kpCmdPtr->cmd |= 0x80;
23756819Sralph 		if (!fp->GraphicsOpen)
23852891Sbostic 			kpCmdPtr->cmd |= 1;
23956819Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
24052891Sbostic 		cp = &kpCmdPtr->par[0];
24152891Sbostic 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
24252891Sbostic 			if (kpCmdPtr->nbytes == 1)
24352891Sbostic 				*cp |= 0x80;
24456819Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
24552891Sbostic 		}
24658974Sralph 		break;
24752891Sbostic 	    }
24852891Sbostic 
24952891Sbostic 	case QIOCADDR:
25056819Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
25152891Sbostic 		break;
25252891Sbostic 
25352891Sbostic 	case QIOWCURSOR:
25456819Sralph 		cfbLoadCursor((unsigned short *)data);
25552891Sbostic 		break;
25652891Sbostic 
25752891Sbostic 	case QIOWCURSORCOLOR:
25856819Sralph 		cfbCursorColor((unsigned int *)data);
25952891Sbostic 		break;
26052891Sbostic 
26152891Sbostic 	case QIOSETCMAP:
26256819Sralph 		cfbLoadColorMap((ColorMap *)data);
26352891Sbostic 		break;
26452891Sbostic 
26552891Sbostic 	case QIOKERNLOOP:
26656819Sralph 		cfbConfigMouse();
26752891Sbostic 		break;
26852891Sbostic 
26952891Sbostic 	case QIOKERNUNLOOP:
27056819Sralph 		cfbDeconfigMouse();
27152891Sbostic 		break;
27252891Sbostic 
27352891Sbostic 	case QIOVIDEOON:
27456819Sralph 		cfbRestoreCursorColor();
27556819Sralph 		bt459_video_on();
27652891Sbostic 		break;
27752891Sbostic 
27852891Sbostic 	case QIOVIDEOOFF:
27956819Sralph 		bt459_video_off();
28052891Sbostic 		break;
28152891Sbostic 
28252891Sbostic 	default:
28352891Sbostic 		printf("cfb0: Unknown ioctl command %x\n", cmd);
28452891Sbostic 		return (EINVAL);
28552891Sbostic 	}
28652891Sbostic 	return (0);
28752891Sbostic }
28852891Sbostic 
28952891Sbostic cfbselect(dev, flag, p)
29052891Sbostic 	dev_t dev;
29152891Sbostic 	int flag;
29252891Sbostic 	struct proc *p;
29352891Sbostic {
29456819Sralph 	struct pmax_fb *fp = &cfbfb;
29552891Sbostic 
29652891Sbostic 	switch (flag) {
29752891Sbostic 	case FREAD:
29856819Sralph 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
29952891Sbostic 			return (1);
30056819Sralph 		selrecord(p, &fp->selp);
30152891Sbostic 		break;
30252891Sbostic 	}
30352891Sbostic 
30452891Sbostic 	return (0);
30552891Sbostic }
30652891Sbostic 
30758974Sralph /*
30858974Sralph  * Return the physical page number that corresponds to byte offset 'off'.
30958974Sralph  */
31058974Sralph /*ARGSUSED*/
31158974Sralph cfbmap(dev, off, prot)
31258974Sralph 	dev_t dev;
31358974Sralph {
31458974Sralph 	int len;
31558974Sralph 
31658974Sralph 	len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu));
31758974Sralph 	if (off < len)
31858974Sralph 		return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off);
31958974Sralph 	off -= len;
32058974Sralph 	if (off >= cfbfb.fr_size)
32158974Sralph 		return (-1);
32258974Sralph 	return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off);
32358974Sralph }
32458974Sralph 
32552891Sbostic static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
32652891Sbostic 
32752891Sbostic /*
32856819Sralph  * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM
32956819Sralph  * defines a 64x64 cursor. If the bt459 does not map the cursor RAM
33056819Sralph  * this way, this code is Screwed!
33152891Sbostic  */
33256819Sralph static void
33356819Sralph cfbLoadCursor(cursor)
33456819Sralph 	u_short *cursor;
33556819Sralph {
33659070Sralph #ifdef PMAX
33756819Sralph 	register int i, j, k, pos;
33856819Sralph 	register u_short ap, bp, out;
33952891Sbostic 
34056819Sralph 	/*
34156819Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
34256819Sralph 	 * for the pmax.
34356819Sralph 	 * XXX This will have to change when the X server knows that this
34456819Sralph 	 * is not a pmax display.
34556819Sralph 	 */
34656819Sralph 	pos = 0;
34756819Sralph 	for (k = 0; k < 16; k++) {
34856819Sralph 		ap = *cursor;
34956819Sralph 		bp = *(cursor + 16);
35056819Sralph 		j = 0;
35156819Sralph 		while (j < 4) {
35256819Sralph 			out = 0;
35356819Sralph 			for (i = 0; i < 4; i++) {
35459824Sralph #ifndef CURSOR_EB
35556819Sralph 				out = (out << 2) | ((ap & 0x1) << 1) |
35656819Sralph 					(bp & 0x1);
35757234Sralph #else
35857234Sralph 				out = ((out >> 2) & 0x3f) |
35957234Sralph 					((ap & 0x1) << 7) |
36057234Sralph 					((bp & 0x1) << 6);
36157234Sralph #endif
36256819Sralph 				ap >>= 1;
36356819Sralph 				bp >>= 1;
36456819Sralph 			}
36556819Sralph 			bt459_set_cursor_ram(pos, out);
36656819Sralph 			pos++;
36756819Sralph 			j++;
36856819Sralph 		}
36956819Sralph 		while (j < 16) {
37056819Sralph 			bt459_set_cursor_ram(pos, 0);
37156819Sralph 			pos++;
37256819Sralph 			j++;
37356819Sralph 		}
37456819Sralph 		cursor++;
37556819Sralph 	}
37656819Sralph 	while (pos < 1024) {
37756819Sralph 		bt459_set_cursor_ram(pos, 0);
37856819Sralph 		pos++;
37956819Sralph 	}
38059070Sralph #endif /* PMAX */
38156819Sralph }
38252891Sbostic 
38352891Sbostic /*
38456819Sralph  * Set a cursor ram value.
38556819Sralph  */
38656819Sralph static void
38756819Sralph bt459_set_cursor_ram(pos, val)
38856819Sralph 	int pos;
38956819Sralph 	register u_char val;
39056819Sralph {
39156819Sralph 	register bt459_regmap_t *regs = (bt459_regmap_t *)
39256819Sralph 		(cfbfb.fr_addr + CFB_OFFSET_BT459);
39356819Sralph 	register int cnt;
39456819Sralph 	u_char nval;
39556819Sralph 
39656819Sralph 	cnt = 0;
39756819Sralph 	do {
39856819Sralph 		bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val);
39956819Sralph 		nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos);
40056819Sralph 	} while (val != nval && ++cnt < 10);
40156819Sralph }
40256819Sralph 
40356819Sralph /*
40452891Sbostic  * Generic register access
40552891Sbostic  */
40656819Sralph static void
40752891Sbostic bt459_select_reg(regs, regno)
40852891Sbostic 	bt459_regmap_t *regs;
40952891Sbostic {
41052891Sbostic 	regs->addr_lo = regno;
41152891Sbostic 	regs->addr_hi = regno >> 8;
41252891Sbostic 	MachEmptyWriteBuffer();
41352891Sbostic }
41452891Sbostic 
41556819Sralph static void
41652891Sbostic bt459_write_reg(regs, regno, val)
41752891Sbostic 	bt459_regmap_t *regs;
41852891Sbostic {
41952891Sbostic 	regs->addr_lo = regno;
42052891Sbostic 	regs->addr_hi = regno >> 8;
42152891Sbostic 	MachEmptyWriteBuffer();
42252891Sbostic 	regs->addr_reg = val;
42352891Sbostic 	MachEmptyWriteBuffer();
42452891Sbostic }
42552891Sbostic 
42656819Sralph static u_char
42752891Sbostic bt459_read_reg(regs, regno)
42852891Sbostic 	bt459_regmap_t *regs;
42952891Sbostic {
43052891Sbostic 	regs->addr_lo = regno;
43152891Sbostic 	regs->addr_hi = regno >> 8;
43252891Sbostic 	MachEmptyWriteBuffer();
43356819Sralph 	return (regs->addr_reg);
43452891Sbostic }
43552891Sbostic 
43652891Sbostic /*
43756819Sralph  * Initialization
43852891Sbostic  */
43956819Sralph int
44056819Sralph cfbinit(cp)
44156819Sralph 	char *cp;
44252891Sbostic {
44356819Sralph 	register bt459_regmap_t *regs;
44456819Sralph 	register struct pmax_fb *fp = &cfbfb;
44552891Sbostic 
44652891Sbostic 	/* check for no frame buffer */
44756819Sralph 	if (badaddr(cp, 4))
44852891Sbostic 		return (0);
44952891Sbostic 
45056819Sralph 	fp->isMono = 0;
45156819Sralph 	fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM);
45258974Sralph 	fp->fr_size = CFB_FB_SIZE;
45357234Sralph 	/*
45458974Sralph 	 * Must be in Uncached space since the fbuaccess structure is
45558974Sralph 	 * mapped into the user's address space uncached.
45657234Sralph 	 */
45757234Sralph 	fp->fbu = (struct fbuaccess *)
45857234Sralph 		MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu));
45956819Sralph 	fp->posCursor = cfbPosCursor;
46057234Sralph 	if (tb_kbdmouseconfig(fp))
46156819Sralph 		return (0);
46252891Sbostic 
46356819Sralph 	/*
46456819Sralph 	 * Initialize the screen.
46556819Sralph 	 */
46656819Sralph 	regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459);
46756819Sralph 
46852891Sbostic 	if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
46952891Sbostic 		return (0);
47052891Sbostic 
47156819Sralph 	/* Reset the chip */
47256819Sralph 	*(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
47352891Sbostic 	DELAY(2000);	/* ???? check right time on specs! ???? */
47452891Sbostic 
47552891Sbostic 	/* use 4:1 input mux */
47652891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD0, 0x40);
47752891Sbostic 
47852891Sbostic 	/* no zooming, no panning */
47952891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD1, 0x00);
48052891Sbostic 
48152891Sbostic 	/*
48252891Sbostic 	 * signature test, X-windows cursor, no overlays, SYNC* PLL,
48352891Sbostic 	 * normal RAM select, 7.5 IRE pedestal, do sync
48452891Sbostic 	 */
48559070Sralph #ifndef PMAX
48652891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc2);
48759070Sralph #else /* PMAX */
48859070Sralph 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc0);
48959070Sralph #endif /* PMAX */
49052891Sbostic 
49152891Sbostic 	/* get all pixel bits */
49252891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
49352891Sbostic 
49452891Sbostic 	/* no blinking */
49552891Sbostic 	bt459_write_reg(regs, BT459_REG_PBM, 0x00);
49652891Sbostic 
49752891Sbostic 	/* no overlay */
49852891Sbostic 	bt459_write_reg(regs, BT459_REG_ORM, 0x00);
49952891Sbostic 
50052891Sbostic 	/* no overlay blink */
50152891Sbostic 	bt459_write_reg(regs, BT459_REG_OBM, 0x00);
50252891Sbostic 
50352891Sbostic 	/* no interleave, no underlay */
50452891Sbostic 	bt459_write_reg(regs, BT459_REG_ILV, 0x00);
50552891Sbostic 
50652891Sbostic 	/* normal operation, no signature analysis */
50752891Sbostic 	bt459_write_reg(regs, BT459_REG_TEST, 0x00);
50852891Sbostic 
50952891Sbostic 	/*
51052891Sbostic 	 * no blinking, 1bit cross hair, XOR reg&crosshair,
51152891Sbostic 	 * no crosshair on either plane 0 or 1,
51252891Sbostic 	 * regular cursor on both planes.
51352891Sbostic 	 */
51452891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
51552891Sbostic 
51652891Sbostic 	/* home cursor */
51752891Sbostic 	bt459_write_reg(regs, BT459_REG_CXLO, 0x00);
51852891Sbostic 	bt459_write_reg(regs, BT459_REG_CXHI, 0x00);
51952891Sbostic 	bt459_write_reg(regs, BT459_REG_CYLO, 0x00);
52052891Sbostic 	bt459_write_reg(regs, BT459_REG_CYHI, 0x00);
52152891Sbostic 
52252891Sbostic 	/* no crosshair window */
52352891Sbostic 	bt459_write_reg(regs, BT459_REG_WXLO, 0x00);
52452891Sbostic 	bt459_write_reg(regs, BT459_REG_WXHI, 0x00);
52552891Sbostic 	bt459_write_reg(regs, BT459_REG_WYLO, 0x00);
52652891Sbostic 	bt459_write_reg(regs, BT459_REG_WYHI, 0x00);
52752891Sbostic 	bt459_write_reg(regs, BT459_REG_WWLO, 0x00);
52852891Sbostic 	bt459_write_reg(regs, BT459_REG_WWHI, 0x00);
52952891Sbostic 	bt459_write_reg(regs, BT459_REG_WHLO, 0x00);
53052891Sbostic 	bt459_write_reg(regs, BT459_REG_WHHI, 0x00);
53152891Sbostic 
53252891Sbostic 	/*
53352891Sbostic 	 * Initialize screen info.
53452891Sbostic 	 */
53556819Sralph 	fp->fbu->scrInfo.max_row = 56;
53656819Sralph 	fp->fbu->scrInfo.max_col = 80;
53756819Sralph 	fp->fbu->scrInfo.max_x = 1024;
53856819Sralph 	fp->fbu->scrInfo.max_y = 864;
53956819Sralph 	fp->fbu->scrInfo.max_cur_x = 1023;
54056819Sralph 	fp->fbu->scrInfo.max_cur_y = 863;
54156819Sralph 	fp->fbu->scrInfo.version = 11;
54256819Sralph 	fp->fbu->scrInfo.mthreshold = 4;
54356819Sralph 	fp->fbu->scrInfo.mscale = 2;
54456819Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
54556819Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
54656819Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
54756819Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
54856819Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
54956819Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
55056819Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
55152891Sbostic 
55252891Sbostic 	/*
55352891Sbostic 	 * Initialize the color map, the screen, and the mouse.
55452891Sbostic 	 */
55556819Sralph 	cfbInitColorMap();
55656819Sralph 	cfbScreenInit();
55756819Sralph 	fbScroll(fp);
55852891Sbostic 
55956819Sralph 	fp->initialized = 1;
56056819Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
56156819Sralph 		cn_tab.cn_fb = fp;
56252891Sbostic 	return (1);
56352891Sbostic }
56452891Sbostic 
56552891Sbostic /*
56652891Sbostic  * ----------------------------------------------------------------------------
56752891Sbostic  *
56856819Sralph  * cfbScreenInit --
56952891Sbostic  *
57052891Sbostic  *	Initialize the screen.
57152891Sbostic  *
57252891Sbostic  * Results:
57352891Sbostic  *	None.
57452891Sbostic  *
57552891Sbostic  * Side effects:
57652891Sbostic  *	The screen is initialized.
57752891Sbostic  *
57852891Sbostic  * ----------------------------------------------------------------------------
57952891Sbostic  */
58052891Sbostic static void
58156819Sralph cfbScreenInit()
58252891Sbostic {
58356819Sralph 	register struct pmax_fb *fp = &cfbfb;
58452891Sbostic 
58552891Sbostic 	/*
58652891Sbostic 	 * Home the cursor.
58756819Sralph 	 * We want an LSI terminal emulation.  We want the graphics
58852891Sbostic 	 * terminal to scroll from the bottom. So start at the bottom.
58952891Sbostic 	 */
59056819Sralph 	fp->row = 55;
59156819Sralph 	fp->col = 0;
59252891Sbostic 
59352891Sbostic 	/*
59452891Sbostic 	 * Load the cursor with the default values
59552891Sbostic 	 *
59652891Sbostic 	 */
59756819Sralph 	cfbLoadCursor(defCursor);
59852891Sbostic }
59952891Sbostic 
60052891Sbostic /*
60152891Sbostic  * ----------------------------------------------------------------------------
60252891Sbostic  *
60352891Sbostic  * RestoreCursorColor --
60452891Sbostic  *
60552891Sbostic  *	Routine to restore the color of the cursor.
60652891Sbostic  *
60752891Sbostic  * Results:
60852891Sbostic  *	None.
60952891Sbostic  *
61052891Sbostic  * Side effects:
61152891Sbostic  *	None.
61252891Sbostic  *
61352891Sbostic  * ----------------------------------------------------------------------------
61452891Sbostic  */
61552891Sbostic static void
61656819Sralph cfbRestoreCursorColor()
61752891Sbostic {
61856819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
61952891Sbostic 	register int i;
62052891Sbostic 
62159070Sralph #ifndef PMAX
62252891Sbostic 	bt459_select_reg(regs, BT459_REG_CCOLOR_2);
62352891Sbostic 	for (i = 0; i < 6; i++) {
62452891Sbostic 		regs->addr_reg = cursor_RGB[i];
62552891Sbostic 		MachEmptyWriteBuffer();
62652891Sbostic 	}
62759070Sralph #else /* PMAX */
62859070Sralph 	bt459_select_reg(regs, BT459_REG_CCOLOR_1);
62959070Sralph 	for (i = 0; i < 3; i++) {
63059070Sralph 		regs->addr_reg = cursor_RGB[i];
63159070Sralph 		MachEmptyWriteBuffer();
63259070Sralph 	}
63359070Sralph 	bt459_select_reg(regs, BT459_REG_CCOLOR_3);
63459070Sralph 	for (i = 3; i < 6; i++) {
63559070Sralph 		regs->addr_reg = cursor_RGB[i];
63659070Sralph 		MachEmptyWriteBuffer();
63759070Sralph 	}
63859070Sralph #endif /* PMAX */
63952891Sbostic }
64052891Sbostic 
64152891Sbostic /*
64252891Sbostic  * ----------------------------------------------------------------------------
64352891Sbostic  *
64452891Sbostic  * CursorColor --
64552891Sbostic  *
64652891Sbostic  *	Set the color of the cursor.
64752891Sbostic  *
64852891Sbostic  * Results:
64952891Sbostic  *	None.
65052891Sbostic  *
65152891Sbostic  * Side effects:
65252891Sbostic  *	None.
65352891Sbostic  *
65452891Sbostic  * ----------------------------------------------------------------------------
65552891Sbostic  */
65652891Sbostic static void
65756819Sralph cfbCursorColor(color)
65852891Sbostic 	unsigned int color[];
65952891Sbostic {
66052891Sbostic 	register int i, j;
66152891Sbostic 
66252891Sbostic 	for (i = 0; i < 6; i++)
66352891Sbostic 		cursor_RGB[i] = (u_char)(color[i] >> 8);
66452891Sbostic 
66556819Sralph 	cfbRestoreCursorColor();
66652891Sbostic }
66752891Sbostic 
66852891Sbostic /*
66952891Sbostic  *----------------------------------------------------------------------
67052891Sbostic  *
67152891Sbostic  * PosCursor --
67252891Sbostic  *
67352891Sbostic  *	Postion the cursor.
67452891Sbostic  *
67552891Sbostic  * Results:
67652891Sbostic  *	None.
67752891Sbostic  *
67852891Sbostic  * Side effects:
67952891Sbostic  *	None.
68052891Sbostic  *
68152891Sbostic  *----------------------------------------------------------------------
68252891Sbostic  */
68356819Sralph void
68456819Sralph cfbPosCursor(x, y)
68552891Sbostic 	register int x, y;
68652891Sbostic {
68756819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
68856819Sralph 	register struct pmax_fb *fp = &cfbfb;
68952891Sbostic 
69056819Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
69156819Sralph 		y = fp->fbu->scrInfo.max_cur_y;
69256819Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
69356819Sralph 		x = fp->fbu->scrInfo.max_cur_x;
69456819Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
69556819Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
69652891Sbostic 
69752891Sbostic 	x += 219;
69852891Sbostic 	y += 34;
69952891Sbostic 
70052891Sbostic 	bt459_select_reg(regs, BT459_REG_CXLO);
70152891Sbostic 	regs->addr_reg = x;
70252891Sbostic 	MachEmptyWriteBuffer();
70352891Sbostic 	regs->addr_reg = x >> 8;
70452891Sbostic 	MachEmptyWriteBuffer();
70552891Sbostic 	regs->addr_reg = y;
70652891Sbostic 	MachEmptyWriteBuffer();
70752891Sbostic 	regs->addr_reg = y >> 8;
70852891Sbostic 	MachEmptyWriteBuffer();
70952891Sbostic }
71052891Sbostic 
71152891Sbostic /*
71252891Sbostic  * ----------------------------------------------------------------------------
71352891Sbostic  *
71452891Sbostic  * InitColorMap --
71552891Sbostic  *
71652891Sbostic  *	Initialize the color map.
71752891Sbostic  *
71852891Sbostic  * Results:
71952891Sbostic  *	None.
72052891Sbostic  *
72152891Sbostic  * Side effects:
72252891Sbostic  *	The colormap is initialized appropriately.
72352891Sbostic  *
72452891Sbostic  * ----------------------------------------------------------------------------
72552891Sbostic  */
72652891Sbostic static void
72756819Sralph cfbInitColorMap()
72852891Sbostic {
72956819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
73052891Sbostic 	register int i;
73152891Sbostic 
73252891Sbostic 	bt459_select_reg(regs, 0);
73352891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73452891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73552891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73652891Sbostic 
73752891Sbostic 	for (i = 1; i < 256; i++) {
73852891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
73952891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74052891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74152891Sbostic 	}
74252891Sbostic 
74352891Sbostic 	for (i = 0; i < 3; i++) {
74452891Sbostic 		cursor_RGB[i] = 0x00;
74552891Sbostic 		cursor_RGB[i + 3] = 0xff;
74652891Sbostic 	}
74756819Sralph 	cfbRestoreCursorColor();
74852891Sbostic }
74952891Sbostic 
75052891Sbostic /*
75152891Sbostic  * ----------------------------------------------------------------------------
75252891Sbostic  *
75352891Sbostic  * LoadColorMap --
75452891Sbostic  *
75552891Sbostic  *	Load the color map.
75652891Sbostic  *
75752891Sbostic  * Results:
75852891Sbostic  *	None.
75952891Sbostic  *
76052891Sbostic  * Side effects:
76152891Sbostic  *	The color map is loaded.
76252891Sbostic  *
76352891Sbostic  * ----------------------------------------------------------------------------
76452891Sbostic  */
76552891Sbostic static void
76656819Sralph cfbLoadColorMap(ptr)
76752891Sbostic 	ColorMap *ptr;
76852891Sbostic {
76956819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
77052891Sbostic 
77152891Sbostic 	if (ptr->index > 256)
77252891Sbostic 		return;
77352891Sbostic 
77452891Sbostic 	bt459_select_reg(regs, ptr->index);
77552891Sbostic 
77652891Sbostic 	regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer();
77752891Sbostic 	regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer();
77852891Sbostic 	regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer();
77952891Sbostic }
78052891Sbostic 
78152891Sbostic /*
78252891Sbostic  * Video on/off state.
78352891Sbostic  */
78456819Sralph static struct vstate {
78552891Sbostic 	u_char	color0[3];	/* saved color map entry zero */
78652891Sbostic 	u_char	off;		/* TRUE if display is off */
78752891Sbostic } vstate;
78852891Sbostic 
78952891Sbostic /*
79052891Sbostic  * ----------------------------------------------------------------------------
79152891Sbostic  *
79256819Sralph  * bt459_video_on
79352891Sbostic  *
79452891Sbostic  *	Enable the video display.
79552891Sbostic  *
79652891Sbostic  * Results:
79752891Sbostic  *	None.
79852891Sbostic  *
79952891Sbostic  * Side effects:
80052891Sbostic  *	The display is enabled.
80152891Sbostic  *
80252891Sbostic  * ----------------------------------------------------------------------------
80352891Sbostic  */
80452891Sbostic static void
80556819Sralph bt459_video_on()
80652891Sbostic {
80756819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
80852891Sbostic 
80952891Sbostic 	if (!vstate.off)
81052891Sbostic 		return;
81152891Sbostic 
81252891Sbostic 	/* restore old color map entry zero */
81352891Sbostic 	bt459_select_reg(regs, 0);
81452891Sbostic 	regs->addr_cmap = vstate.color0[0];
81552891Sbostic 	MachEmptyWriteBuffer();
81652891Sbostic 	regs->addr_cmap = vstate.color0[1];
81752891Sbostic 	MachEmptyWriteBuffer();
81852891Sbostic 	regs->addr_cmap = vstate.color0[2];
81952891Sbostic 	MachEmptyWriteBuffer();
82052891Sbostic 
82152891Sbostic 	/* enable normal display */
82252891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
82352891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
82452891Sbostic 
82552891Sbostic 	vstate.off = 0;
82652891Sbostic }
82752891Sbostic 
82852891Sbostic /*
82952891Sbostic  * ----------------------------------------------------------------------------
83052891Sbostic  *
83156819Sralph  * bt459_video_off
83252891Sbostic  *
83352891Sbostic  *	Disable the video display.
83452891Sbostic  *
83552891Sbostic  * Results:
83652891Sbostic  *	None.
83752891Sbostic  *
83852891Sbostic  * Side effects:
83952891Sbostic  *	The display is disabled.
84052891Sbostic  *
84152891Sbostic  * ----------------------------------------------------------------------------
84252891Sbostic  */
84352891Sbostic static void
84456819Sralph bt459_video_off()
84552891Sbostic {
84656819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
84752891Sbostic 
84852891Sbostic 	if (vstate.off)
84952891Sbostic 		return;
85052891Sbostic 
85152891Sbostic 	/* save old color map entry zero */
85252891Sbostic 	bt459_select_reg(regs, 0);
85352891Sbostic 	vstate.color0[0] = regs->addr_cmap;
85452891Sbostic 	vstate.color0[1] = regs->addr_cmap;
85552891Sbostic 	vstate.color0[2] = regs->addr_cmap;
85652891Sbostic 
85752891Sbostic 	/* set color map entry zero to zero */
85852891Sbostic 	bt459_select_reg(regs, 0);
85952891Sbostic 	regs->addr_cmap = 0;
86052891Sbostic 	MachEmptyWriteBuffer();
86152891Sbostic 	regs->addr_cmap = 0;
86252891Sbostic 	MachEmptyWriteBuffer();
86352891Sbostic 	regs->addr_cmap = 0;
86452891Sbostic 	MachEmptyWriteBuffer();
86552891Sbostic 
86652891Sbostic 	/* disable display */
86752891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0);
86852891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0);
86952891Sbostic 
87052891Sbostic 	vstate.off = 1;
87152891Sbostic }
87256819Sralph 
87356819Sralph /*
87456819Sralph  * cfb keyboard and mouse input. Just punt to the generic ones in fb.c
87556819Sralph  */
87656819Sralph void
87756819Sralph cfbKbdEvent(ch)
87856819Sralph 	int ch;
87956819Sralph {
88056819Sralph 	fbKbdEvent(ch, &cfbfb);
88156819Sralph }
88256819Sralph 
88356819Sralph void
88456819Sralph cfbMouseEvent(newRepPtr)
88556819Sralph 	MouseReport *newRepPtr;
88656819Sralph {
88756819Sralph 	fbMouseEvent(newRepPtr, &cfbfb);
88856819Sralph }
88956819Sralph 
89056819Sralph void
89156819Sralph cfbMouseButtons(newRepPtr)
89256819Sralph 	MouseReport *newRepPtr;
89356819Sralph {
89456819Sralph 	fbMouseButtons(newRepPtr, &cfbfb);
89556819Sralph }
89656819Sralph 
89756819Sralph /*
89856819Sralph  * Configure the mouse and keyboard based on machine type
89956819Sralph  */
90056819Sralph static void
90156819Sralph cfbConfigMouse()
90256819Sralph {
90356819Sralph 	int s;
90456819Sralph 
90556819Sralph 	s = spltty();
90656819Sralph 	switch (pmax_boardtype) {
90756819Sralph #if NDC > 0
90856819Sralph 	case DS_3MAX:
90956819Sralph 		dcDivertXInput = cfbKbdEvent;
91056819Sralph 		dcMouseEvent = cfbMouseEvent;
91156819Sralph 		dcMouseButtons = cfbMouseButtons;
91256819Sralph 		break;
91352891Sbostic #endif
91456819Sralph #if NSCC > 1
91556819Sralph 	case DS_3MIN:
91656819Sralph 		sccDivertXInput = cfbKbdEvent;
91756819Sralph 		sccMouseEvent = cfbMouseEvent;
91856819Sralph 		sccMouseButtons = cfbMouseButtons;
91956819Sralph 		break;
92056819Sralph #endif
92156819Sralph #if NDTOP > 0
92256819Sralph 	case DS_MAXINE:
92356819Sralph 		dtopDivertXInput = cfbKbdEvent;
92456819Sralph 		dtopMouseEvent = cfbMouseEvent;
92556819Sralph 		dtopMouseButtons = cfbMouseButtons;
92656819Sralph 		break;
92756819Sralph #endif
92856819Sralph 	default:
92956819Sralph 		printf("Can't configure mouse/keyboard\n");
93056819Sralph 	};
93156819Sralph 	splx(s);
93256819Sralph }
93356819Sralph 
93456819Sralph /*
93556819Sralph  * and deconfigure them
93656819Sralph  */
93756819Sralph static void
93856819Sralph cfbDeconfigMouse()
93956819Sralph {
94056819Sralph 	int s;
94156819Sralph 
94256819Sralph 	s = spltty();
94356819Sralph 	switch (pmax_boardtype) {
94456819Sralph #if NDC > 0
94556819Sralph 	case DS_3MAX:
94656819Sralph 		dcDivertXInput = (void (*)())0;
94756819Sralph 		dcMouseEvent = (void (*)())0;
94856819Sralph 		dcMouseButtons = (void (*)())0;
94956819Sralph 		break;
95056819Sralph #endif
95156819Sralph #if NSCC > 1
95256819Sralph 	case DS_3MIN:
95356819Sralph 		sccDivertXInput = (void (*)())0;
95456819Sralph 		sccMouseEvent = (void (*)())0;
95556819Sralph 		sccMouseButtons = (void (*)())0;
95656819Sralph 		break;
95756819Sralph #endif
95856819Sralph #if NDTOP > 0
95956819Sralph 	case DS_MAXINE:
96056819Sralph 		dtopDivertXInput = (void (*)())0;
96156819Sralph 		dtopMouseEvent = (void (*)())0;
96256819Sralph 		dtopMouseButtons = (void (*)())0;
96356819Sralph 		break;
96456819Sralph #endif
96556819Sralph 	default:
96656819Sralph 		printf("Can't deconfigure mouse/keyboard\n");
96756819Sralph 	};
96856819Sralph }
96956819Sralph #endif /* NCFB */
970