xref: /csrg-svn/sys/pmax/dev/cfb.c (revision 58974)
152891Sbostic /*-
252891Sbostic  * Copyright (c) 1992 The Regents of the University of California.
352891Sbostic  * 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*58974Sralph  *	@(#)cfb.c	7.7 (Berkeley) 04/05/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 
8352891Sbostic /*
8452891Sbostic  * These need to be mapped into user space.
8552891Sbostic  */
8656819Sralph struct fbuaccess cfbu;
8756819Sralph struct pmax_fb cfbfb;
8852891Sbostic 
8952891Sbostic /*
9052891Sbostic  * Forward references.
9152891Sbostic  */
9256819Sralph static void cfbScreenInit();
9356819Sralph static void cfbLoadCursor();
9456819Sralph static void cfbRestoreCursorColor();
9556819Sralph static void cfbCursorColor();
9656819Sralph void cfbPosCursor();
9756819Sralph static void cfbInitColorMap();
9856819Sralph static void cfbLoadColorMap();
9956819Sralph static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off();
10056819Sralph static void bt459_select_reg(), bt459_write_reg();
10156819Sralph static u_char bt459_read_reg();
10256819Sralph static void cfbConfigMouse(), cfbDeconfigMouse();
10352891Sbostic 
10456819Sralph void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons();
10556819Sralph #if NDC > 0
10652891Sbostic extern void (*dcDivertXInput)();
10752891Sbostic extern void (*dcMouseEvent)();
10852891Sbostic extern void (*dcMouseButtons)();
10956819Sralph #endif
11056819Sralph #if NSCC > 0
11156819Sralph extern void (*sccDivertXInput)();
11256819Sralph extern void (*sccMouseEvent)();
11356819Sralph extern void (*sccMouseButtons)();
11456819Sralph #endif
11556819Sralph #if NDTOP > 0
11656819Sralph extern void (*dtopDivertXInput)();
11756819Sralph extern void (*dtopMouseEvent)();
11856819Sralph extern void (*dtopMouseButtons)();
11956819Sralph #endif
12056819Sralph extern int pmax_boardtype;
12156819Sralph extern u_short defCursor[32];
12256819Sralph extern struct consdev cn_tab;
12352891Sbostic 
12452891Sbostic int	cfbprobe();
12552891Sbostic struct	driver cfbdriver = {
12652891Sbostic 	"cfb", cfbprobe, 0, 0,
12752891Sbostic };
12852891Sbostic 
12956819Sralph #define	CFB_OFFSET_VRAM		0x0		/* from module's base */
13056819Sralph #define CFB_OFFSET_BT459	0x200000	/* Bt459 registers */
13156819Sralph #define CFB_OFFSET_IREQ		0x300000	/* Interrupt req. control */
13256819Sralph #define CFB_OFFSET_ROM		0x380000	/* Diagnostic ROM */
13356819Sralph #define CFB_OFFSET_RESET	0x3c0000	/* Bt459 resets on writes */
134*58974Sralph #define CFB_FB_SIZE		0x100000	/* frame buffer size */
13556819Sralph 
13652891Sbostic /*
13752891Sbostic  * Test to see if device is present.
13852891Sbostic  * Return true if found and initialized ok.
13952891Sbostic  */
14056819Sralph /*ARGSUSED*/
14152891Sbostic cfbprobe(cp)
14252891Sbostic 	register struct pmax_ctlr *cp;
14352891Sbostic {
14456819Sralph 	register struct pmax_fb *fp = &cfbfb;
14552891Sbostic 
14656819Sralph 	if (!fp->initialized && !cfbinit(cp->pmax_addr))
14756819Sralph 		return (0);
14856819Sralph 	printf("cfb0 (color display)\n");
14952891Sbostic 	return (1);
15052891Sbostic }
15152891Sbostic 
15252891Sbostic /*ARGSUSED*/
15352891Sbostic cfbopen(dev, flag)
15452891Sbostic 	dev_t dev;
15552891Sbostic 	int flag;
15652891Sbostic {
15756819Sralph 	register struct pmax_fb *fp = &cfbfb;
15856819Sralph 	int s;
15952891Sbostic 
16056819Sralph 	if (!fp->initialized)
16152891Sbostic 		return (ENXIO);
16256819Sralph 	if (fp->GraphicsOpen)
16352891Sbostic 		return (EBUSY);
16452891Sbostic 
16556819Sralph 	fp->GraphicsOpen = 1;
16656819Sralph 	cfbInitColorMap();
16752891Sbostic 	/*
16852891Sbostic 	 * Set up event queue for later
16952891Sbostic 	 */
17056819Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
17156819Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
17256819Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
17356819Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
17456819Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
17556819Sralph 	cfbConfigMouse();
17652891Sbostic 	return (0);
17752891Sbostic }
17852891Sbostic 
17952891Sbostic /*ARGSUSED*/
18052891Sbostic cfbclose(dev, flag)
18152891Sbostic 	dev_t dev;
18252891Sbostic 	int flag;
18352891Sbostic {
18456819Sralph 	register struct pmax_fb *fp = &cfbfb;
18552959Sralph 	int s;
18652891Sbostic 
18756819Sralph 	if (!fp->GraphicsOpen)
18852891Sbostic 		return (EBADF);
18952891Sbostic 
19056819Sralph 	fp->GraphicsOpen = 0;
19156819Sralph 	cfbInitColorMap();
19256819Sralph 	cfbDeconfigMouse();
19356819Sralph 	cfbScreenInit();
19456819Sralph 	bzero((caddr_t)fp->fr_addr, 1024 * 864);
19556819Sralph 	cfbPosCursor(fp->col * 8, fp->row * 15);
19652891Sbostic 	return (0);
19752891Sbostic }
19852891Sbostic 
19952891Sbostic /*ARGSUSED*/
200*58974Sralph cfbioctl(dev, cmd, data, flag, p)
20152891Sbostic 	dev_t dev;
20252891Sbostic 	caddr_t data;
203*58974Sralph 	struct proc *p;
20452891Sbostic {
20556819Sralph 	register struct pmax_fb *fp = &cfbfb;
20652959Sralph 	int s;
20752891Sbostic 
20852891Sbostic 	switch (cmd) {
20952891Sbostic 	case QIOCGINFO:
210*58974Sralph 		return (fbmmap(fp, dev, data, p));
21152891Sbostic 
21252891Sbostic 	case QIOCPMSTATE:
21352891Sbostic 		/*
21452891Sbostic 		 * Set mouse state.
21552891Sbostic 		 */
21656819Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
21756819Sralph 		cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
21852891Sbostic 		break;
21952891Sbostic 
22052891Sbostic 	case QIOCINIT:
22152891Sbostic 		/*
22252891Sbostic 		 * Initialize the screen.
22352891Sbostic 		 */
22456819Sralph 		cfbScreenInit();
22552891Sbostic 		break;
22652891Sbostic 
22752891Sbostic 	case QIOCKPCMD:
22852891Sbostic 	    {
22952891Sbostic 		pmKpCmd *kpCmdPtr;
23052891Sbostic 		unsigned char *cp;
23152891Sbostic 
23252891Sbostic 		kpCmdPtr = (pmKpCmd *)data;
23352891Sbostic 		if (kpCmdPtr->nbytes == 0)
23452891Sbostic 			kpCmdPtr->cmd |= 0x80;
23556819Sralph 		if (!fp->GraphicsOpen)
23652891Sbostic 			kpCmdPtr->cmd |= 1;
23756819Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
23852891Sbostic 		cp = &kpCmdPtr->par[0];
23952891Sbostic 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
24052891Sbostic 			if (kpCmdPtr->nbytes == 1)
24152891Sbostic 				*cp |= 0x80;
24256819Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
24352891Sbostic 		}
244*58974Sralph 		break;
24552891Sbostic 	    }
24652891Sbostic 
24752891Sbostic 	case QIOCADDR:
24856819Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
24952891Sbostic 		break;
25052891Sbostic 
25152891Sbostic 	case QIOWCURSOR:
25256819Sralph 		cfbLoadCursor((unsigned short *)data);
25352891Sbostic 		break;
25452891Sbostic 
25552891Sbostic 	case QIOWCURSORCOLOR:
25656819Sralph 		cfbCursorColor((unsigned int *)data);
25752891Sbostic 		break;
25852891Sbostic 
25952891Sbostic 	case QIOSETCMAP:
26056819Sralph 		cfbLoadColorMap((ColorMap *)data);
26152891Sbostic 		break;
26252891Sbostic 
26352891Sbostic 	case QIOKERNLOOP:
26456819Sralph 		cfbConfigMouse();
26552891Sbostic 		break;
26652891Sbostic 
26752891Sbostic 	case QIOKERNUNLOOP:
26856819Sralph 		cfbDeconfigMouse();
26952891Sbostic 		break;
27052891Sbostic 
27152891Sbostic 	case QIOVIDEOON:
27256819Sralph 		cfbRestoreCursorColor();
27356819Sralph 		bt459_video_on();
27452891Sbostic 		break;
27552891Sbostic 
27652891Sbostic 	case QIOVIDEOOFF:
27756819Sralph 		bt459_video_off();
27852891Sbostic 		break;
27952891Sbostic 
28052891Sbostic 	default:
28152891Sbostic 		printf("cfb0: Unknown ioctl command %x\n", cmd);
28252891Sbostic 		return (EINVAL);
28352891Sbostic 	}
28452891Sbostic 	return (0);
28552891Sbostic }
28652891Sbostic 
28752891Sbostic cfbselect(dev, flag, p)
28852891Sbostic 	dev_t dev;
28952891Sbostic 	int flag;
29052891Sbostic 	struct proc *p;
29152891Sbostic {
29256819Sralph 	struct pmax_fb *fp = &cfbfb;
29352891Sbostic 
29452891Sbostic 	switch (flag) {
29552891Sbostic 	case FREAD:
29656819Sralph 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
29752891Sbostic 			return (1);
29856819Sralph 		selrecord(p, &fp->selp);
29952891Sbostic 		break;
30052891Sbostic 	}
30152891Sbostic 
30252891Sbostic 	return (0);
30352891Sbostic }
30452891Sbostic 
305*58974Sralph /*
306*58974Sralph  * Return the physical page number that corresponds to byte offset 'off'.
307*58974Sralph  */
308*58974Sralph /*ARGSUSED*/
309*58974Sralph cfbmap(dev, off, prot)
310*58974Sralph 	dev_t dev;
311*58974Sralph {
312*58974Sralph 	int len;
313*58974Sralph 
314*58974Sralph 	len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu));
315*58974Sralph 	if (off < len)
316*58974Sralph 		return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off);
317*58974Sralph 	off -= len;
318*58974Sralph 	if (off >= cfbfb.fr_size)
319*58974Sralph 		return (-1);
320*58974Sralph 	return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off);
321*58974Sralph }
322*58974Sralph 
32352891Sbostic static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
32452891Sbostic 
32552891Sbostic /*
32656819Sralph  * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM
32756819Sralph  * defines a 64x64 cursor. If the bt459 does not map the cursor RAM
32856819Sralph  * this way, this code is Screwed!
32952891Sbostic  */
33056819Sralph static void
33156819Sralph cfbLoadCursor(cursor)
33256819Sralph 	u_short *cursor;
33356819Sralph {
33456819Sralph 	register int i, j, k, pos;
33556819Sralph 	register u_short ap, bp, out;
33652891Sbostic 
33756819Sralph 	/*
33856819Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
33956819Sralph 	 * for the pmax.
34056819Sralph 	 * XXX This will have to change when the X server knows that this
34156819Sralph 	 * is not a pmax display.
34256819Sralph 	 */
34356819Sralph 	pos = 0;
34456819Sralph 	for (k = 0; k < 16; k++) {
34556819Sralph 		ap = *cursor;
34656819Sralph 		bp = *(cursor + 16);
34756819Sralph 		j = 0;
34856819Sralph 		while (j < 4) {
34956819Sralph 			out = 0;
35056819Sralph 			for (i = 0; i < 4; i++) {
35157234Sralph #ifdef CURSOR_EL
35256819Sralph 				out = (out << 2) | ((ap & 0x1) << 1) |
35356819Sralph 					(bp & 0x1);
35457234Sralph #else
35557234Sralph 				out = ((out >> 2) & 0x3f) |
35657234Sralph 					((ap & 0x1) << 7) |
35757234Sralph 					((bp & 0x1) << 6);
35857234Sralph #endif
35956819Sralph 				ap >>= 1;
36056819Sralph 				bp >>= 1;
36156819Sralph 			}
36256819Sralph 			bt459_set_cursor_ram(pos, out);
36356819Sralph 			pos++;
36456819Sralph 			j++;
36556819Sralph 		}
36656819Sralph 		while (j < 16) {
36756819Sralph 			bt459_set_cursor_ram(pos, 0);
36856819Sralph 			pos++;
36956819Sralph 			j++;
37056819Sralph 		}
37156819Sralph 		cursor++;
37256819Sralph 	}
37356819Sralph 	while (pos < 1024) {
37456819Sralph 		bt459_set_cursor_ram(pos, 0);
37556819Sralph 		pos++;
37656819Sralph 	}
37756819Sralph }
37852891Sbostic 
37952891Sbostic /*
38056819Sralph  * Set a cursor ram value.
38156819Sralph  */
38256819Sralph static void
38356819Sralph bt459_set_cursor_ram(pos, val)
38456819Sralph 	int pos;
38556819Sralph 	register u_char val;
38656819Sralph {
38756819Sralph 	register bt459_regmap_t *regs = (bt459_regmap_t *)
38856819Sralph 		(cfbfb.fr_addr + CFB_OFFSET_BT459);
38956819Sralph 	register int cnt;
39056819Sralph 	u_char nval;
39156819Sralph 
39256819Sralph 	cnt = 0;
39356819Sralph 	do {
39456819Sralph 		bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val);
39556819Sralph 		nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos);
39656819Sralph 	} while (val != nval && ++cnt < 10);
39756819Sralph }
39856819Sralph 
39956819Sralph /*
40052891Sbostic  * Generic register access
40152891Sbostic  */
40256819Sralph static void
40352891Sbostic bt459_select_reg(regs, regno)
40452891Sbostic 	bt459_regmap_t *regs;
40552891Sbostic {
40652891Sbostic 	regs->addr_lo = regno;
40752891Sbostic 	regs->addr_hi = regno >> 8;
40852891Sbostic 	MachEmptyWriteBuffer();
40952891Sbostic }
41052891Sbostic 
41156819Sralph static void
41252891Sbostic bt459_write_reg(regs, regno, val)
41352891Sbostic 	bt459_regmap_t *regs;
41452891Sbostic {
41552891Sbostic 	regs->addr_lo = regno;
41652891Sbostic 	regs->addr_hi = regno >> 8;
41752891Sbostic 	MachEmptyWriteBuffer();
41852891Sbostic 	regs->addr_reg = val;
41952891Sbostic 	MachEmptyWriteBuffer();
42052891Sbostic }
42152891Sbostic 
42256819Sralph static u_char
42352891Sbostic bt459_read_reg(regs, regno)
42452891Sbostic 	bt459_regmap_t *regs;
42552891Sbostic {
42652891Sbostic 	regs->addr_lo = regno;
42752891Sbostic 	regs->addr_hi = regno >> 8;
42852891Sbostic 	MachEmptyWriteBuffer();
42956819Sralph 	return (regs->addr_reg);
43052891Sbostic }
43152891Sbostic 
43252891Sbostic /*
43356819Sralph  * Initialization
43452891Sbostic  */
43556819Sralph int
43656819Sralph cfbinit(cp)
43756819Sralph 	char *cp;
43852891Sbostic {
43956819Sralph 	register bt459_regmap_t *regs;
44056819Sralph 	register struct pmax_fb *fp = &cfbfb;
44152891Sbostic 
44252891Sbostic 	/* check for no frame buffer */
44356819Sralph 	if (badaddr(cp, 4))
44452891Sbostic 		return (0);
44552891Sbostic 
44656819Sralph 	fp->isMono = 0;
44756819Sralph 	fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM);
448*58974Sralph 	fp->fr_size = CFB_FB_SIZE;
44957234Sralph 	/*
450*58974Sralph 	 * Must be in Uncached space since the fbuaccess structure is
451*58974Sralph 	 * mapped into the user's address space uncached.
45257234Sralph 	 */
45357234Sralph 	fp->fbu = (struct fbuaccess *)
45457234Sralph 		MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu));
45556819Sralph 	fp->posCursor = cfbPosCursor;
45657234Sralph 	if (tb_kbdmouseconfig(fp))
45756819Sralph 		return (0);
45852891Sbostic 
45956819Sralph 	/*
46056819Sralph 	 * Initialize the screen.
46156819Sralph 	 */
46256819Sralph 	regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459);
46356819Sralph 
46452891Sbostic 	if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
46552891Sbostic 		return (0);
46652891Sbostic 
46756819Sralph 	/* Reset the chip */
46856819Sralph 	*(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
46952891Sbostic 	DELAY(2000);	/* ???? check right time on specs! ???? */
47052891Sbostic 
47152891Sbostic 	/* use 4:1 input mux */
47252891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD0, 0x40);
47352891Sbostic 
47452891Sbostic 	/* no zooming, no panning */
47552891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD1, 0x00);
47652891Sbostic 
47752891Sbostic 	/*
47852891Sbostic 	 * signature test, X-windows cursor, no overlays, SYNC* PLL,
47952891Sbostic 	 * normal RAM select, 7.5 IRE pedestal, do sync
48052891Sbostic 	 */
48152891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc2);
48252891Sbostic 
48352891Sbostic 	/* get all pixel bits */
48452891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
48552891Sbostic 
48652891Sbostic 	/* no blinking */
48752891Sbostic 	bt459_write_reg(regs, BT459_REG_PBM, 0x00);
48852891Sbostic 
48952891Sbostic 	/* no overlay */
49052891Sbostic 	bt459_write_reg(regs, BT459_REG_ORM, 0x00);
49152891Sbostic 
49252891Sbostic 	/* no overlay blink */
49352891Sbostic 	bt459_write_reg(regs, BT459_REG_OBM, 0x00);
49452891Sbostic 
49552891Sbostic 	/* no interleave, no underlay */
49652891Sbostic 	bt459_write_reg(regs, BT459_REG_ILV, 0x00);
49752891Sbostic 
49852891Sbostic 	/* normal operation, no signature analysis */
49952891Sbostic 	bt459_write_reg(regs, BT459_REG_TEST, 0x00);
50052891Sbostic 
50152891Sbostic 	/*
50252891Sbostic 	 * no blinking, 1bit cross hair, XOR reg&crosshair,
50352891Sbostic 	 * no crosshair on either plane 0 or 1,
50452891Sbostic 	 * regular cursor on both planes.
50552891Sbostic 	 */
50652891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
50752891Sbostic 
50852891Sbostic 	/* home cursor */
50952891Sbostic 	bt459_write_reg(regs, BT459_REG_CXLO, 0x00);
51052891Sbostic 	bt459_write_reg(regs, BT459_REG_CXHI, 0x00);
51152891Sbostic 	bt459_write_reg(regs, BT459_REG_CYLO, 0x00);
51252891Sbostic 	bt459_write_reg(regs, BT459_REG_CYHI, 0x00);
51352891Sbostic 
51452891Sbostic 	/* no crosshair window */
51552891Sbostic 	bt459_write_reg(regs, BT459_REG_WXLO, 0x00);
51652891Sbostic 	bt459_write_reg(regs, BT459_REG_WXHI, 0x00);
51752891Sbostic 	bt459_write_reg(regs, BT459_REG_WYLO, 0x00);
51852891Sbostic 	bt459_write_reg(regs, BT459_REG_WYHI, 0x00);
51952891Sbostic 	bt459_write_reg(regs, BT459_REG_WWLO, 0x00);
52052891Sbostic 	bt459_write_reg(regs, BT459_REG_WWHI, 0x00);
52152891Sbostic 	bt459_write_reg(regs, BT459_REG_WHLO, 0x00);
52252891Sbostic 	bt459_write_reg(regs, BT459_REG_WHHI, 0x00);
52352891Sbostic 
52452891Sbostic 	/*
52552891Sbostic 	 * Initialize screen info.
52652891Sbostic 	 */
52756819Sralph 	fp->fbu->scrInfo.max_row = 56;
52856819Sralph 	fp->fbu->scrInfo.max_col = 80;
52956819Sralph 	fp->fbu->scrInfo.max_x = 1024;
53056819Sralph 	fp->fbu->scrInfo.max_y = 864;
53156819Sralph 	fp->fbu->scrInfo.max_cur_x = 1023;
53256819Sralph 	fp->fbu->scrInfo.max_cur_y = 863;
53356819Sralph 	fp->fbu->scrInfo.version = 11;
53456819Sralph 	fp->fbu->scrInfo.mthreshold = 4;
53556819Sralph 	fp->fbu->scrInfo.mscale = 2;
53656819Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
53756819Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
53856819Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
53956819Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
54056819Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
54156819Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
54256819Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
54352891Sbostic 
54452891Sbostic 	/*
54552891Sbostic 	 * Initialize the color map, the screen, and the mouse.
54652891Sbostic 	 */
54756819Sralph 	cfbInitColorMap();
54856819Sralph 	cfbScreenInit();
54956819Sralph 	fbScroll(fp);
55052891Sbostic 
55156819Sralph 	fp->initialized = 1;
55256819Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
55356819Sralph 		cn_tab.cn_fb = fp;
55452891Sbostic 	return (1);
55552891Sbostic }
55652891Sbostic 
55752891Sbostic /*
55852891Sbostic  * ----------------------------------------------------------------------------
55952891Sbostic  *
56056819Sralph  * cfbScreenInit --
56152891Sbostic  *
56252891Sbostic  *	Initialize the screen.
56352891Sbostic  *
56452891Sbostic  * Results:
56552891Sbostic  *	None.
56652891Sbostic  *
56752891Sbostic  * Side effects:
56852891Sbostic  *	The screen is initialized.
56952891Sbostic  *
57052891Sbostic  * ----------------------------------------------------------------------------
57152891Sbostic  */
57252891Sbostic static void
57356819Sralph cfbScreenInit()
57452891Sbostic {
57556819Sralph 	register struct pmax_fb *fp = &cfbfb;
57652891Sbostic 
57752891Sbostic 	/*
57852891Sbostic 	 * Home the cursor.
57956819Sralph 	 * We want an LSI terminal emulation.  We want the graphics
58052891Sbostic 	 * terminal to scroll from the bottom. So start at the bottom.
58152891Sbostic 	 */
58256819Sralph 	fp->row = 55;
58356819Sralph 	fp->col = 0;
58452891Sbostic 
58552891Sbostic 	/*
58652891Sbostic 	 * Load the cursor with the default values
58752891Sbostic 	 *
58852891Sbostic 	 */
58956819Sralph 	cfbLoadCursor(defCursor);
59052891Sbostic }
59152891Sbostic 
59252891Sbostic /*
59352891Sbostic  * ----------------------------------------------------------------------------
59452891Sbostic  *
59552891Sbostic  * RestoreCursorColor --
59652891Sbostic  *
59752891Sbostic  *	Routine to restore the color of the cursor.
59852891Sbostic  *
59952891Sbostic  * Results:
60052891Sbostic  *	None.
60152891Sbostic  *
60252891Sbostic  * Side effects:
60352891Sbostic  *	None.
60452891Sbostic  *
60552891Sbostic  * ----------------------------------------------------------------------------
60652891Sbostic  */
60752891Sbostic static void
60856819Sralph cfbRestoreCursorColor()
60952891Sbostic {
61056819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
61152891Sbostic 	register int i;
61252891Sbostic 
61352891Sbostic 	bt459_select_reg(regs, BT459_REG_CCOLOR_2);
61452891Sbostic 	for (i = 0; i < 6; i++) {
61552891Sbostic 		regs->addr_reg = cursor_RGB[i];
61652891Sbostic 		MachEmptyWriteBuffer();
61752891Sbostic 	}
61852891Sbostic }
61952891Sbostic 
62052891Sbostic /*
62152891Sbostic  * ----------------------------------------------------------------------------
62252891Sbostic  *
62352891Sbostic  * CursorColor --
62452891Sbostic  *
62552891Sbostic  *	Set the color of the cursor.
62652891Sbostic  *
62752891Sbostic  * Results:
62852891Sbostic  *	None.
62952891Sbostic  *
63052891Sbostic  * Side effects:
63152891Sbostic  *	None.
63252891Sbostic  *
63352891Sbostic  * ----------------------------------------------------------------------------
63452891Sbostic  */
63552891Sbostic static void
63656819Sralph cfbCursorColor(color)
63752891Sbostic 	unsigned int color[];
63852891Sbostic {
63952891Sbostic 	register int i, j;
64052891Sbostic 
64152891Sbostic 	for (i = 0; i < 6; i++)
64252891Sbostic 		cursor_RGB[i] = (u_char)(color[i] >> 8);
64352891Sbostic 
64456819Sralph 	cfbRestoreCursorColor();
64552891Sbostic }
64652891Sbostic 
64752891Sbostic /*
64852891Sbostic  *----------------------------------------------------------------------
64952891Sbostic  *
65052891Sbostic  * PosCursor --
65152891Sbostic  *
65252891Sbostic  *	Postion the cursor.
65352891Sbostic  *
65452891Sbostic  * Results:
65552891Sbostic  *	None.
65652891Sbostic  *
65752891Sbostic  * Side effects:
65852891Sbostic  *	None.
65952891Sbostic  *
66052891Sbostic  *----------------------------------------------------------------------
66152891Sbostic  */
66256819Sralph void
66356819Sralph cfbPosCursor(x, y)
66452891Sbostic 	register int x, y;
66552891Sbostic {
66656819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
66756819Sralph 	register struct pmax_fb *fp = &cfbfb;
66852891Sbostic 
66956819Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
67056819Sralph 		y = fp->fbu->scrInfo.max_cur_y;
67156819Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
67256819Sralph 		x = fp->fbu->scrInfo.max_cur_x;
67356819Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
67456819Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
67552891Sbostic 
67652891Sbostic 	x += 219;
67752891Sbostic 	y += 34;
67852891Sbostic 
67952891Sbostic 	bt459_select_reg(regs, BT459_REG_CXLO);
68052891Sbostic 	regs->addr_reg = x;
68152891Sbostic 	MachEmptyWriteBuffer();
68252891Sbostic 	regs->addr_reg = x >> 8;
68352891Sbostic 	MachEmptyWriteBuffer();
68452891Sbostic 	regs->addr_reg = y;
68552891Sbostic 	MachEmptyWriteBuffer();
68652891Sbostic 	regs->addr_reg = y >> 8;
68752891Sbostic 	MachEmptyWriteBuffer();
68852891Sbostic }
68952891Sbostic 
69052891Sbostic /*
69152891Sbostic  * ----------------------------------------------------------------------------
69252891Sbostic  *
69352891Sbostic  * InitColorMap --
69452891Sbostic  *
69552891Sbostic  *	Initialize the color map.
69652891Sbostic  *
69752891Sbostic  * Results:
69852891Sbostic  *	None.
69952891Sbostic  *
70052891Sbostic  * Side effects:
70152891Sbostic  *	The colormap is initialized appropriately.
70252891Sbostic  *
70352891Sbostic  * ----------------------------------------------------------------------------
70452891Sbostic  */
70552891Sbostic static void
70656819Sralph cfbInitColorMap()
70752891Sbostic {
70856819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
70952891Sbostic 	register int i;
71052891Sbostic 
71152891Sbostic 	bt459_select_reg(regs, 0);
71252891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
71352891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
71452891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
71552891Sbostic 
71652891Sbostic 	for (i = 1; i < 256; i++) {
71752891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
71852891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
71952891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
72052891Sbostic 	}
72152891Sbostic 
72252891Sbostic 	for (i = 0; i < 3; i++) {
72352891Sbostic 		cursor_RGB[i] = 0x00;
72452891Sbostic 		cursor_RGB[i + 3] = 0xff;
72552891Sbostic 	}
72656819Sralph 	cfbRestoreCursorColor();
72752891Sbostic }
72852891Sbostic 
72952891Sbostic /*
73052891Sbostic  * ----------------------------------------------------------------------------
73152891Sbostic  *
73252891Sbostic  * LoadColorMap --
73352891Sbostic  *
73452891Sbostic  *	Load the color map.
73552891Sbostic  *
73652891Sbostic  * Results:
73752891Sbostic  *	None.
73852891Sbostic  *
73952891Sbostic  * Side effects:
74052891Sbostic  *	The color map is loaded.
74152891Sbostic  *
74252891Sbostic  * ----------------------------------------------------------------------------
74352891Sbostic  */
74452891Sbostic static void
74556819Sralph cfbLoadColorMap(ptr)
74652891Sbostic 	ColorMap *ptr;
74752891Sbostic {
74856819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
74952891Sbostic 
75052891Sbostic 	if (ptr->index > 256)
75152891Sbostic 		return;
75252891Sbostic 
75352891Sbostic 	bt459_select_reg(regs, ptr->index);
75452891Sbostic 
75552891Sbostic 	regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer();
75652891Sbostic 	regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer();
75752891Sbostic 	regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer();
75852891Sbostic }
75952891Sbostic 
76052891Sbostic /*
76152891Sbostic  * Video on/off state.
76252891Sbostic  */
76356819Sralph static struct vstate {
76452891Sbostic 	u_char	color0[3];	/* saved color map entry zero */
76552891Sbostic 	u_char	off;		/* TRUE if display is off */
76652891Sbostic } vstate;
76752891Sbostic 
76852891Sbostic /*
76952891Sbostic  * ----------------------------------------------------------------------------
77052891Sbostic  *
77156819Sralph  * bt459_video_on
77252891Sbostic  *
77352891Sbostic  *	Enable the video display.
77452891Sbostic  *
77552891Sbostic  * Results:
77652891Sbostic  *	None.
77752891Sbostic  *
77852891Sbostic  * Side effects:
77952891Sbostic  *	The display is enabled.
78052891Sbostic  *
78152891Sbostic  * ----------------------------------------------------------------------------
78252891Sbostic  */
78352891Sbostic static void
78456819Sralph bt459_video_on()
78552891Sbostic {
78656819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
78752891Sbostic 
78852891Sbostic 	if (!vstate.off)
78952891Sbostic 		return;
79052891Sbostic 
79152891Sbostic 	/* restore old color map entry zero */
79252891Sbostic 	bt459_select_reg(regs, 0);
79352891Sbostic 	regs->addr_cmap = vstate.color0[0];
79452891Sbostic 	MachEmptyWriteBuffer();
79552891Sbostic 	regs->addr_cmap = vstate.color0[1];
79652891Sbostic 	MachEmptyWriteBuffer();
79752891Sbostic 	regs->addr_cmap = vstate.color0[2];
79852891Sbostic 	MachEmptyWriteBuffer();
79952891Sbostic 
80052891Sbostic 	/* enable normal display */
80152891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
80252891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
80352891Sbostic 
80452891Sbostic 	vstate.off = 0;
80552891Sbostic }
80652891Sbostic 
80752891Sbostic /*
80852891Sbostic  * ----------------------------------------------------------------------------
80952891Sbostic  *
81056819Sralph  * bt459_video_off
81152891Sbostic  *
81252891Sbostic  *	Disable the video display.
81352891Sbostic  *
81452891Sbostic  * Results:
81552891Sbostic  *	None.
81652891Sbostic  *
81752891Sbostic  * Side effects:
81852891Sbostic  *	The display is disabled.
81952891Sbostic  *
82052891Sbostic  * ----------------------------------------------------------------------------
82152891Sbostic  */
82252891Sbostic static void
82356819Sralph bt459_video_off()
82452891Sbostic {
82556819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
82652891Sbostic 
82752891Sbostic 	if (vstate.off)
82852891Sbostic 		return;
82952891Sbostic 
83052891Sbostic 	/* save old color map entry zero */
83152891Sbostic 	bt459_select_reg(regs, 0);
83252891Sbostic 	vstate.color0[0] = regs->addr_cmap;
83352891Sbostic 	vstate.color0[1] = regs->addr_cmap;
83452891Sbostic 	vstate.color0[2] = regs->addr_cmap;
83552891Sbostic 
83652891Sbostic 	/* set color map entry zero to zero */
83752891Sbostic 	bt459_select_reg(regs, 0);
83852891Sbostic 	regs->addr_cmap = 0;
83952891Sbostic 	MachEmptyWriteBuffer();
84052891Sbostic 	regs->addr_cmap = 0;
84152891Sbostic 	MachEmptyWriteBuffer();
84252891Sbostic 	regs->addr_cmap = 0;
84352891Sbostic 	MachEmptyWriteBuffer();
84452891Sbostic 
84552891Sbostic 	/* disable display */
84652891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0);
84752891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0);
84852891Sbostic 
84952891Sbostic 	vstate.off = 1;
85052891Sbostic }
85156819Sralph 
85256819Sralph /*
85356819Sralph  * cfb keyboard and mouse input. Just punt to the generic ones in fb.c
85456819Sralph  */
85556819Sralph void
85656819Sralph cfbKbdEvent(ch)
85756819Sralph 	int ch;
85856819Sralph {
85956819Sralph 	fbKbdEvent(ch, &cfbfb);
86056819Sralph }
86156819Sralph 
86256819Sralph void
86356819Sralph cfbMouseEvent(newRepPtr)
86456819Sralph 	MouseReport *newRepPtr;
86556819Sralph {
86656819Sralph 	fbMouseEvent(newRepPtr, &cfbfb);
86756819Sralph }
86856819Sralph 
86956819Sralph void
87056819Sralph cfbMouseButtons(newRepPtr)
87156819Sralph 	MouseReport *newRepPtr;
87256819Sralph {
87356819Sralph 	fbMouseButtons(newRepPtr, &cfbfb);
87456819Sralph }
87556819Sralph 
87656819Sralph /*
87756819Sralph  * Configure the mouse and keyboard based on machine type
87856819Sralph  */
87956819Sralph static void
88056819Sralph cfbConfigMouse()
88156819Sralph {
88256819Sralph 	int s;
88356819Sralph 
88456819Sralph 	s = spltty();
88556819Sralph 	switch (pmax_boardtype) {
88656819Sralph #if NDC > 0
88756819Sralph 	case DS_3MAX:
88856819Sralph 		dcDivertXInput = cfbKbdEvent;
88956819Sralph 		dcMouseEvent = cfbMouseEvent;
89056819Sralph 		dcMouseButtons = cfbMouseButtons;
89156819Sralph 		break;
89252891Sbostic #endif
89356819Sralph #if NSCC > 1
89456819Sralph 	case DS_3MIN:
89556819Sralph 		sccDivertXInput = cfbKbdEvent;
89656819Sralph 		sccMouseEvent = cfbMouseEvent;
89756819Sralph 		sccMouseButtons = cfbMouseButtons;
89856819Sralph 		break;
89956819Sralph #endif
90056819Sralph #if NDTOP > 0
90156819Sralph 	case DS_MAXINE:
90256819Sralph 		dtopDivertXInput = cfbKbdEvent;
90356819Sralph 		dtopMouseEvent = cfbMouseEvent;
90456819Sralph 		dtopMouseButtons = cfbMouseButtons;
90556819Sralph 		break;
90656819Sralph #endif
90756819Sralph 	default:
90856819Sralph 		printf("Can't configure mouse/keyboard\n");
90956819Sralph 	};
91056819Sralph 	splx(s);
91156819Sralph }
91256819Sralph 
91356819Sralph /*
91456819Sralph  * and deconfigure them
91556819Sralph  */
91656819Sralph static void
91756819Sralph cfbDeconfigMouse()
91856819Sralph {
91956819Sralph 	int s;
92056819Sralph 
92156819Sralph 	s = spltty();
92256819Sralph 	switch (pmax_boardtype) {
92356819Sralph #if NDC > 0
92456819Sralph 	case DS_3MAX:
92556819Sralph 		dcDivertXInput = (void (*)())0;
92656819Sralph 		dcMouseEvent = (void (*)())0;
92756819Sralph 		dcMouseButtons = (void (*)())0;
92856819Sralph 		break;
92956819Sralph #endif
93056819Sralph #if NSCC > 1
93156819Sralph 	case DS_3MIN:
93256819Sralph 		sccDivertXInput = (void (*)())0;
93356819Sralph 		sccMouseEvent = (void (*)())0;
93456819Sralph 		sccMouseButtons = (void (*)())0;
93556819Sralph 		break;
93656819Sralph #endif
93756819Sralph #if NDTOP > 0
93856819Sralph 	case DS_MAXINE:
93956819Sralph 		dtopDivertXInput = (void (*)())0;
94056819Sralph 		dtopMouseEvent = (void (*)())0;
94156819Sralph 		dtopMouseButtons = (void (*)())0;
94256819Sralph 		break;
94356819Sralph #endif
94456819Sralph 	default:
94556819Sralph 		printf("Can't deconfigure mouse/keyboard\n");
94656819Sralph 	};
94756819Sralph }
94856819Sralph #endif /* NCFB */
949