xref: /csrg-svn/sys/pmax/dev/cfb.c (revision 69799)
152891Sbostic /*-
263205Sbostic  * Copyright (c) 1992, 1993
363205Sbostic  *	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*69799Sralph  *	@(#)cfb.c	8.2 (Berkeley) 06/02/95
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*/
cfbprobe(cp)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*/
cfbopen(dev,flag)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*/
cfbclose(dev,flag)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*/
cfbioctl(dev,cmd,data,flag,p)20258974Sralph cfbioctl(dev, cmd, data, flag, p)
20352891Sbostic 	dev_t dev;
204*69799Sralph 	u_long cmd;
20552891Sbostic 	caddr_t data;
20658974Sralph 	struct proc *p;
20752891Sbostic {
20856819Sralph 	register struct pmax_fb *fp = &cfbfb;
20952959Sralph 	int s;
21052891Sbostic 
21152891Sbostic 	switch (cmd) {
21252891Sbostic 	case QIOCGINFO:
21358974Sralph 		return (fbmmap(fp, dev, data, p));
21452891Sbostic 
21552891Sbostic 	case QIOCPMSTATE:
21652891Sbostic 		/*
21752891Sbostic 		 * Set mouse state.
21852891Sbostic 		 */
21956819Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
22056819Sralph 		cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
22152891Sbostic 		break;
22252891Sbostic 
22352891Sbostic 	case QIOCINIT:
22452891Sbostic 		/*
22552891Sbostic 		 * Initialize the screen.
22652891Sbostic 		 */
22756819Sralph 		cfbScreenInit();
22852891Sbostic 		break;
22952891Sbostic 
23052891Sbostic 	case QIOCKPCMD:
23152891Sbostic 	    {
23252891Sbostic 		pmKpCmd *kpCmdPtr;
23352891Sbostic 		unsigned char *cp;
23452891Sbostic 
23552891Sbostic 		kpCmdPtr = (pmKpCmd *)data;
23652891Sbostic 		if (kpCmdPtr->nbytes == 0)
23752891Sbostic 			kpCmdPtr->cmd |= 0x80;
23856819Sralph 		if (!fp->GraphicsOpen)
23952891Sbostic 			kpCmdPtr->cmd |= 1;
24056819Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
24152891Sbostic 		cp = &kpCmdPtr->par[0];
24252891Sbostic 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
24352891Sbostic 			if (kpCmdPtr->nbytes == 1)
24452891Sbostic 				*cp |= 0x80;
24556819Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
24652891Sbostic 		}
24758974Sralph 		break;
24852891Sbostic 	    }
24952891Sbostic 
25052891Sbostic 	case QIOCADDR:
25156819Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
25252891Sbostic 		break;
25352891Sbostic 
25452891Sbostic 	case QIOWCURSOR:
25556819Sralph 		cfbLoadCursor((unsigned short *)data);
25652891Sbostic 		break;
25752891Sbostic 
25852891Sbostic 	case QIOWCURSORCOLOR:
25956819Sralph 		cfbCursorColor((unsigned int *)data);
26052891Sbostic 		break;
26152891Sbostic 
26252891Sbostic 	case QIOSETCMAP:
26356819Sralph 		cfbLoadColorMap((ColorMap *)data);
26452891Sbostic 		break;
26552891Sbostic 
26652891Sbostic 	case QIOKERNLOOP:
26756819Sralph 		cfbConfigMouse();
26852891Sbostic 		break;
26952891Sbostic 
27052891Sbostic 	case QIOKERNUNLOOP:
27156819Sralph 		cfbDeconfigMouse();
27252891Sbostic 		break;
27352891Sbostic 
27452891Sbostic 	case QIOVIDEOON:
27556819Sralph 		cfbRestoreCursorColor();
27656819Sralph 		bt459_video_on();
27752891Sbostic 		break;
27852891Sbostic 
27952891Sbostic 	case QIOVIDEOOFF:
28056819Sralph 		bt459_video_off();
28152891Sbostic 		break;
28252891Sbostic 
28352891Sbostic 	default:
28452891Sbostic 		printf("cfb0: Unknown ioctl command %x\n", cmd);
28552891Sbostic 		return (EINVAL);
28652891Sbostic 	}
28752891Sbostic 	return (0);
28852891Sbostic }
28952891Sbostic 
cfbselect(dev,flag,p)29052891Sbostic cfbselect(dev, flag, p)
29152891Sbostic 	dev_t dev;
29252891Sbostic 	int flag;
29352891Sbostic 	struct proc *p;
29452891Sbostic {
29556819Sralph 	struct pmax_fb *fp = &cfbfb;
29652891Sbostic 
29752891Sbostic 	switch (flag) {
29852891Sbostic 	case FREAD:
29956819Sralph 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
30052891Sbostic 			return (1);
30156819Sralph 		selrecord(p, &fp->selp);
30252891Sbostic 		break;
30352891Sbostic 	}
30452891Sbostic 
30552891Sbostic 	return (0);
30652891Sbostic }
30752891Sbostic 
30858974Sralph /*
30958974Sralph  * Return the physical page number that corresponds to byte offset 'off'.
31058974Sralph  */
31158974Sralph /*ARGSUSED*/
cfbmap(dev,off,prot)31258974Sralph cfbmap(dev, off, prot)
31358974Sralph 	dev_t dev;
31458974Sralph {
31558974Sralph 	int len;
31658974Sralph 
31758974Sralph 	len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu));
31858974Sralph 	if (off < len)
31958974Sralph 		return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off);
32058974Sralph 	off -= len;
32158974Sralph 	if (off >= cfbfb.fr_size)
32258974Sralph 		return (-1);
32358974Sralph 	return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off);
32458974Sralph }
32558974Sralph 
32652891Sbostic static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
32752891Sbostic 
32852891Sbostic /*
32956819Sralph  * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM
33056819Sralph  * defines a 64x64 cursor. If the bt459 does not map the cursor RAM
33156819Sralph  * this way, this code is Screwed!
33252891Sbostic  */
33356819Sralph static void
cfbLoadCursor(cursor)33456819Sralph cfbLoadCursor(cursor)
33556819Sralph 	u_short *cursor;
33656819Sralph {
33759070Sralph #ifdef PMAX
33856819Sralph 	register int i, j, k, pos;
33956819Sralph 	register u_short ap, bp, out;
34052891Sbostic 
34156819Sralph 	/*
34256819Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
34356819Sralph 	 * for the pmax.
34456819Sralph 	 * XXX This will have to change when the X server knows that this
34556819Sralph 	 * is not a pmax display.
34656819Sralph 	 */
34756819Sralph 	pos = 0;
34856819Sralph 	for (k = 0; k < 16; k++) {
34956819Sralph 		ap = *cursor;
35056819Sralph 		bp = *(cursor + 16);
35156819Sralph 		j = 0;
35256819Sralph 		while (j < 4) {
35356819Sralph 			out = 0;
35456819Sralph 			for (i = 0; i < 4; i++) {
35559824Sralph #ifndef CURSOR_EB
35656819Sralph 				out = (out << 2) | ((ap & 0x1) << 1) |
35756819Sralph 					(bp & 0x1);
35857234Sralph #else
35957234Sralph 				out = ((out >> 2) & 0x3f) |
36057234Sralph 					((ap & 0x1) << 7) |
36157234Sralph 					((bp & 0x1) << 6);
36257234Sralph #endif
36356819Sralph 				ap >>= 1;
36456819Sralph 				bp >>= 1;
36556819Sralph 			}
36656819Sralph 			bt459_set_cursor_ram(pos, out);
36756819Sralph 			pos++;
36856819Sralph 			j++;
36956819Sralph 		}
37056819Sralph 		while (j < 16) {
37156819Sralph 			bt459_set_cursor_ram(pos, 0);
37256819Sralph 			pos++;
37356819Sralph 			j++;
37456819Sralph 		}
37556819Sralph 		cursor++;
37656819Sralph 	}
37756819Sralph 	while (pos < 1024) {
37856819Sralph 		bt459_set_cursor_ram(pos, 0);
37956819Sralph 		pos++;
38056819Sralph 	}
38159070Sralph #endif /* PMAX */
38256819Sralph }
38352891Sbostic 
38452891Sbostic /*
38556819Sralph  * Set a cursor ram value.
38656819Sralph  */
38756819Sralph static void
bt459_set_cursor_ram(pos,val)38856819Sralph bt459_set_cursor_ram(pos, val)
38956819Sralph 	int pos;
39056819Sralph 	register u_char val;
39156819Sralph {
39256819Sralph 	register bt459_regmap_t *regs = (bt459_regmap_t *)
39356819Sralph 		(cfbfb.fr_addr + CFB_OFFSET_BT459);
39456819Sralph 	register int cnt;
39556819Sralph 	u_char nval;
39656819Sralph 
39756819Sralph 	cnt = 0;
39856819Sralph 	do {
39956819Sralph 		bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val);
40056819Sralph 		nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos);
40156819Sralph 	} while (val != nval && ++cnt < 10);
40256819Sralph }
40356819Sralph 
40456819Sralph /*
40552891Sbostic  * Generic register access
40652891Sbostic  */
40756819Sralph static void
bt459_select_reg(regs,regno)40852891Sbostic bt459_select_reg(regs, regno)
40952891Sbostic 	bt459_regmap_t *regs;
41052891Sbostic {
41152891Sbostic 	regs->addr_lo = regno;
41252891Sbostic 	regs->addr_hi = regno >> 8;
41352891Sbostic 	MachEmptyWriteBuffer();
41452891Sbostic }
41552891Sbostic 
41656819Sralph static void
bt459_write_reg(regs,regno,val)41752891Sbostic bt459_write_reg(regs, regno, val)
41852891Sbostic 	bt459_regmap_t *regs;
41952891Sbostic {
42052891Sbostic 	regs->addr_lo = regno;
42152891Sbostic 	regs->addr_hi = regno >> 8;
42252891Sbostic 	MachEmptyWriteBuffer();
42352891Sbostic 	regs->addr_reg = val;
42452891Sbostic 	MachEmptyWriteBuffer();
42552891Sbostic }
42652891Sbostic 
42756819Sralph static u_char
bt459_read_reg(regs,regno)42852891Sbostic bt459_read_reg(regs, regno)
42952891Sbostic 	bt459_regmap_t *regs;
43052891Sbostic {
43152891Sbostic 	regs->addr_lo = regno;
43252891Sbostic 	regs->addr_hi = regno >> 8;
43352891Sbostic 	MachEmptyWriteBuffer();
43456819Sralph 	return (regs->addr_reg);
43552891Sbostic }
43652891Sbostic 
43752891Sbostic /*
43856819Sralph  * Initialization
43952891Sbostic  */
44056819Sralph int
cfbinit(cp)44156819Sralph cfbinit(cp)
44256819Sralph 	char *cp;
44352891Sbostic {
44456819Sralph 	register bt459_regmap_t *regs;
44556819Sralph 	register struct pmax_fb *fp = &cfbfb;
44652891Sbostic 
44752891Sbostic 	/* check for no frame buffer */
44856819Sralph 	if (badaddr(cp, 4))
44952891Sbostic 		return (0);
45052891Sbostic 
45156819Sralph 	fp->isMono = 0;
45256819Sralph 	fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM);
45358974Sralph 	fp->fr_size = CFB_FB_SIZE;
45457234Sralph 	/*
45558974Sralph 	 * Must be in Uncached space since the fbuaccess structure is
45658974Sralph 	 * mapped into the user's address space uncached.
45757234Sralph 	 */
45857234Sralph 	fp->fbu = (struct fbuaccess *)
45957234Sralph 		MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu));
46056819Sralph 	fp->posCursor = cfbPosCursor;
46157234Sralph 	if (tb_kbdmouseconfig(fp))
46256819Sralph 		return (0);
46352891Sbostic 
46456819Sralph 	/*
46556819Sralph 	 * Initialize the screen.
46656819Sralph 	 */
46756819Sralph 	regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459);
46856819Sralph 
46952891Sbostic 	if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
47052891Sbostic 		return (0);
47152891Sbostic 
47256819Sralph 	/* Reset the chip */
47356819Sralph 	*(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
47452891Sbostic 	DELAY(2000);	/* ???? check right time on specs! ???? */
47552891Sbostic 
47652891Sbostic 	/* use 4:1 input mux */
47752891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD0, 0x40);
47852891Sbostic 
47952891Sbostic 	/* no zooming, no panning */
48052891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD1, 0x00);
48152891Sbostic 
48252891Sbostic 	/*
48352891Sbostic 	 * signature test, X-windows cursor, no overlays, SYNC* PLL,
48452891Sbostic 	 * normal RAM select, 7.5 IRE pedestal, do sync
48552891Sbostic 	 */
48659070Sralph #ifndef PMAX
48752891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc2);
48859070Sralph #else /* PMAX */
48959070Sralph 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc0);
49059070Sralph #endif /* PMAX */
49152891Sbostic 
49252891Sbostic 	/* get all pixel bits */
49352891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
49452891Sbostic 
49552891Sbostic 	/* no blinking */
49652891Sbostic 	bt459_write_reg(regs, BT459_REG_PBM, 0x00);
49752891Sbostic 
49852891Sbostic 	/* no overlay */
49952891Sbostic 	bt459_write_reg(regs, BT459_REG_ORM, 0x00);
50052891Sbostic 
50152891Sbostic 	/* no overlay blink */
50252891Sbostic 	bt459_write_reg(regs, BT459_REG_OBM, 0x00);
50352891Sbostic 
50452891Sbostic 	/* no interleave, no underlay */
50552891Sbostic 	bt459_write_reg(regs, BT459_REG_ILV, 0x00);
50652891Sbostic 
50752891Sbostic 	/* normal operation, no signature analysis */
50852891Sbostic 	bt459_write_reg(regs, BT459_REG_TEST, 0x00);
50952891Sbostic 
51052891Sbostic 	/*
51152891Sbostic 	 * no blinking, 1bit cross hair, XOR reg&crosshair,
51252891Sbostic 	 * no crosshair on either plane 0 or 1,
51352891Sbostic 	 * regular cursor on both planes.
51452891Sbostic 	 */
51552891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
51652891Sbostic 
51752891Sbostic 	/* home cursor */
51852891Sbostic 	bt459_write_reg(regs, BT459_REG_CXLO, 0x00);
51952891Sbostic 	bt459_write_reg(regs, BT459_REG_CXHI, 0x00);
52052891Sbostic 	bt459_write_reg(regs, BT459_REG_CYLO, 0x00);
52152891Sbostic 	bt459_write_reg(regs, BT459_REG_CYHI, 0x00);
52252891Sbostic 
52352891Sbostic 	/* no crosshair window */
52452891Sbostic 	bt459_write_reg(regs, BT459_REG_WXLO, 0x00);
52552891Sbostic 	bt459_write_reg(regs, BT459_REG_WXHI, 0x00);
52652891Sbostic 	bt459_write_reg(regs, BT459_REG_WYLO, 0x00);
52752891Sbostic 	bt459_write_reg(regs, BT459_REG_WYHI, 0x00);
52852891Sbostic 	bt459_write_reg(regs, BT459_REG_WWLO, 0x00);
52952891Sbostic 	bt459_write_reg(regs, BT459_REG_WWHI, 0x00);
53052891Sbostic 	bt459_write_reg(regs, BT459_REG_WHLO, 0x00);
53152891Sbostic 	bt459_write_reg(regs, BT459_REG_WHHI, 0x00);
53252891Sbostic 
53352891Sbostic 	/*
53452891Sbostic 	 * Initialize screen info.
53552891Sbostic 	 */
53656819Sralph 	fp->fbu->scrInfo.max_row = 56;
53756819Sralph 	fp->fbu->scrInfo.max_col = 80;
53856819Sralph 	fp->fbu->scrInfo.max_x = 1024;
53956819Sralph 	fp->fbu->scrInfo.max_y = 864;
54056819Sralph 	fp->fbu->scrInfo.max_cur_x = 1023;
54156819Sralph 	fp->fbu->scrInfo.max_cur_y = 863;
54256819Sralph 	fp->fbu->scrInfo.version = 11;
54356819Sralph 	fp->fbu->scrInfo.mthreshold = 4;
54456819Sralph 	fp->fbu->scrInfo.mscale = 2;
54556819Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
54656819Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
54756819Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
54856819Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
54956819Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
55056819Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
55156819Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
55252891Sbostic 
55352891Sbostic 	/*
55452891Sbostic 	 * Initialize the color map, the screen, and the mouse.
55552891Sbostic 	 */
55656819Sralph 	cfbInitColorMap();
55756819Sralph 	cfbScreenInit();
55856819Sralph 	fbScroll(fp);
55952891Sbostic 
56056819Sralph 	fp->initialized = 1;
56156819Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
56256819Sralph 		cn_tab.cn_fb = fp;
56352891Sbostic 	return (1);
56452891Sbostic }
56552891Sbostic 
56652891Sbostic /*
56752891Sbostic  * ----------------------------------------------------------------------------
56852891Sbostic  *
56956819Sralph  * cfbScreenInit --
57052891Sbostic  *
57152891Sbostic  *	Initialize the screen.
57252891Sbostic  *
57352891Sbostic  * Results:
57452891Sbostic  *	None.
57552891Sbostic  *
57652891Sbostic  * Side effects:
57752891Sbostic  *	The screen is initialized.
57852891Sbostic  *
57952891Sbostic  * ----------------------------------------------------------------------------
58052891Sbostic  */
58152891Sbostic static void
cfbScreenInit()58256819Sralph cfbScreenInit()
58352891Sbostic {
58456819Sralph 	register struct pmax_fb *fp = &cfbfb;
58552891Sbostic 
58652891Sbostic 	/*
58752891Sbostic 	 * Home the cursor.
58856819Sralph 	 * We want an LSI terminal emulation.  We want the graphics
58952891Sbostic 	 * terminal to scroll from the bottom. So start at the bottom.
59052891Sbostic 	 */
59156819Sralph 	fp->row = 55;
59256819Sralph 	fp->col = 0;
59352891Sbostic 
59452891Sbostic 	/*
59552891Sbostic 	 * Load the cursor with the default values
59652891Sbostic 	 *
59752891Sbostic 	 */
59856819Sralph 	cfbLoadCursor(defCursor);
59952891Sbostic }
60052891Sbostic 
60152891Sbostic /*
60252891Sbostic  * ----------------------------------------------------------------------------
60352891Sbostic  *
60452891Sbostic  * RestoreCursorColor --
60552891Sbostic  *
60652891Sbostic  *	Routine to restore the color of the cursor.
60752891Sbostic  *
60852891Sbostic  * Results:
60952891Sbostic  *	None.
61052891Sbostic  *
61152891Sbostic  * Side effects:
61252891Sbostic  *	None.
61352891Sbostic  *
61452891Sbostic  * ----------------------------------------------------------------------------
61552891Sbostic  */
61652891Sbostic static void
cfbRestoreCursorColor()61756819Sralph cfbRestoreCursorColor()
61852891Sbostic {
61956819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
62052891Sbostic 	register int i;
62152891Sbostic 
62259070Sralph #ifndef PMAX
62352891Sbostic 	bt459_select_reg(regs, BT459_REG_CCOLOR_2);
62452891Sbostic 	for (i = 0; i < 6; i++) {
62552891Sbostic 		regs->addr_reg = cursor_RGB[i];
62652891Sbostic 		MachEmptyWriteBuffer();
62752891Sbostic 	}
62859070Sralph #else /* PMAX */
62959070Sralph 	bt459_select_reg(regs, BT459_REG_CCOLOR_1);
63059070Sralph 	for (i = 0; i < 3; i++) {
63159070Sralph 		regs->addr_reg = cursor_RGB[i];
63259070Sralph 		MachEmptyWriteBuffer();
63359070Sralph 	}
63459070Sralph 	bt459_select_reg(regs, BT459_REG_CCOLOR_3);
63559070Sralph 	for (i = 3; i < 6; i++) {
63659070Sralph 		regs->addr_reg = cursor_RGB[i];
63759070Sralph 		MachEmptyWriteBuffer();
63859070Sralph 	}
63959070Sralph #endif /* PMAX */
64052891Sbostic }
64152891Sbostic 
64252891Sbostic /*
64352891Sbostic  * ----------------------------------------------------------------------------
64452891Sbostic  *
64552891Sbostic  * CursorColor --
64652891Sbostic  *
64752891Sbostic  *	Set the color of the cursor.
64852891Sbostic  *
64952891Sbostic  * Results:
65052891Sbostic  *	None.
65152891Sbostic  *
65252891Sbostic  * Side effects:
65352891Sbostic  *	None.
65452891Sbostic  *
65552891Sbostic  * ----------------------------------------------------------------------------
65652891Sbostic  */
65752891Sbostic static void
cfbCursorColor(color)65856819Sralph cfbCursorColor(color)
65952891Sbostic 	unsigned int color[];
66052891Sbostic {
66152891Sbostic 	register int i, j;
66252891Sbostic 
66352891Sbostic 	for (i = 0; i < 6; i++)
66452891Sbostic 		cursor_RGB[i] = (u_char)(color[i] >> 8);
66552891Sbostic 
66656819Sralph 	cfbRestoreCursorColor();
66752891Sbostic }
66852891Sbostic 
66952891Sbostic /*
67052891Sbostic  *----------------------------------------------------------------------
67152891Sbostic  *
67252891Sbostic  * PosCursor --
67352891Sbostic  *
67452891Sbostic  *	Postion the cursor.
67552891Sbostic  *
67652891Sbostic  * Results:
67752891Sbostic  *	None.
67852891Sbostic  *
67952891Sbostic  * Side effects:
68052891Sbostic  *	None.
68152891Sbostic  *
68252891Sbostic  *----------------------------------------------------------------------
68352891Sbostic  */
68456819Sralph void
cfbPosCursor(x,y)68556819Sralph cfbPosCursor(x, y)
68652891Sbostic 	register int x, y;
68752891Sbostic {
68856819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
68956819Sralph 	register struct pmax_fb *fp = &cfbfb;
69052891Sbostic 
69156819Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
69256819Sralph 		y = fp->fbu->scrInfo.max_cur_y;
69356819Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
69456819Sralph 		x = fp->fbu->scrInfo.max_cur_x;
69556819Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
69656819Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
69752891Sbostic 
69852891Sbostic 	x += 219;
69952891Sbostic 	y += 34;
70052891Sbostic 
70152891Sbostic 	bt459_select_reg(regs, BT459_REG_CXLO);
70252891Sbostic 	regs->addr_reg = x;
70352891Sbostic 	MachEmptyWriteBuffer();
70452891Sbostic 	regs->addr_reg = x >> 8;
70552891Sbostic 	MachEmptyWriteBuffer();
70652891Sbostic 	regs->addr_reg = y;
70752891Sbostic 	MachEmptyWriteBuffer();
70852891Sbostic 	regs->addr_reg = y >> 8;
70952891Sbostic 	MachEmptyWriteBuffer();
71052891Sbostic }
71152891Sbostic 
71252891Sbostic /*
71352891Sbostic  * ----------------------------------------------------------------------------
71452891Sbostic  *
71552891Sbostic  * InitColorMap --
71652891Sbostic  *
71752891Sbostic  *	Initialize the color map.
71852891Sbostic  *
71952891Sbostic  * Results:
72052891Sbostic  *	None.
72152891Sbostic  *
72252891Sbostic  * Side effects:
72352891Sbostic  *	The colormap is initialized appropriately.
72452891Sbostic  *
72552891Sbostic  * ----------------------------------------------------------------------------
72652891Sbostic  */
72752891Sbostic static void
cfbInitColorMap()72856819Sralph cfbInitColorMap()
72952891Sbostic {
73056819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
73152891Sbostic 	register int i;
73252891Sbostic 
73352891Sbostic 	bt459_select_reg(regs, 0);
73452891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73552891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73652891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
73752891Sbostic 
73852891Sbostic 	for (i = 1; i < 256; i++) {
73952891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74052891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74152891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74252891Sbostic 	}
74352891Sbostic 
74452891Sbostic 	for (i = 0; i < 3; i++) {
74552891Sbostic 		cursor_RGB[i] = 0x00;
74652891Sbostic 		cursor_RGB[i + 3] = 0xff;
74752891Sbostic 	}
74856819Sralph 	cfbRestoreCursorColor();
74952891Sbostic }
75052891Sbostic 
75152891Sbostic /*
75252891Sbostic  * ----------------------------------------------------------------------------
75352891Sbostic  *
75452891Sbostic  * LoadColorMap --
75552891Sbostic  *
75652891Sbostic  *	Load the color map.
75752891Sbostic  *
75852891Sbostic  * Results:
75952891Sbostic  *	None.
76052891Sbostic  *
76152891Sbostic  * Side effects:
76252891Sbostic  *	The color map is loaded.
76352891Sbostic  *
76452891Sbostic  * ----------------------------------------------------------------------------
76552891Sbostic  */
76652891Sbostic static void
cfbLoadColorMap(ptr)76756819Sralph cfbLoadColorMap(ptr)
76852891Sbostic 	ColorMap *ptr;
76952891Sbostic {
77056819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
77152891Sbostic 
77252891Sbostic 	if (ptr->index > 256)
77352891Sbostic 		return;
77452891Sbostic 
77552891Sbostic 	bt459_select_reg(regs, ptr->index);
77652891Sbostic 
77752891Sbostic 	regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer();
77852891Sbostic 	regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer();
77952891Sbostic 	regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer();
78052891Sbostic }
78152891Sbostic 
78252891Sbostic /*
78352891Sbostic  * Video on/off state.
78452891Sbostic  */
78556819Sralph static struct vstate {
78652891Sbostic 	u_char	color0[3];	/* saved color map entry zero */
78752891Sbostic 	u_char	off;		/* TRUE if display is off */
78852891Sbostic } vstate;
78952891Sbostic 
79052891Sbostic /*
79152891Sbostic  * ----------------------------------------------------------------------------
79252891Sbostic  *
79356819Sralph  * bt459_video_on
79452891Sbostic  *
79552891Sbostic  *	Enable the video display.
79652891Sbostic  *
79752891Sbostic  * Results:
79852891Sbostic  *	None.
79952891Sbostic  *
80052891Sbostic  * Side effects:
80152891Sbostic  *	The display is enabled.
80252891Sbostic  *
80352891Sbostic  * ----------------------------------------------------------------------------
80452891Sbostic  */
80552891Sbostic static void
bt459_video_on()80656819Sralph bt459_video_on()
80752891Sbostic {
80856819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
80952891Sbostic 
81052891Sbostic 	if (!vstate.off)
81152891Sbostic 		return;
81252891Sbostic 
81352891Sbostic 	/* restore old color map entry zero */
81452891Sbostic 	bt459_select_reg(regs, 0);
81552891Sbostic 	regs->addr_cmap = vstate.color0[0];
81652891Sbostic 	MachEmptyWriteBuffer();
81752891Sbostic 	regs->addr_cmap = vstate.color0[1];
81852891Sbostic 	MachEmptyWriteBuffer();
81952891Sbostic 	regs->addr_cmap = vstate.color0[2];
82052891Sbostic 	MachEmptyWriteBuffer();
82152891Sbostic 
82252891Sbostic 	/* enable normal display */
82352891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
82452891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
82552891Sbostic 
82652891Sbostic 	vstate.off = 0;
82752891Sbostic }
82852891Sbostic 
82952891Sbostic /*
83052891Sbostic  * ----------------------------------------------------------------------------
83152891Sbostic  *
83256819Sralph  * bt459_video_off
83352891Sbostic  *
83452891Sbostic  *	Disable the video display.
83552891Sbostic  *
83652891Sbostic  * Results:
83752891Sbostic  *	None.
83852891Sbostic  *
83952891Sbostic  * Side effects:
84052891Sbostic  *	The display is disabled.
84152891Sbostic  *
84252891Sbostic  * ----------------------------------------------------------------------------
84352891Sbostic  */
84452891Sbostic static void
bt459_video_off()84556819Sralph bt459_video_off()
84652891Sbostic {
84756819Sralph 	bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
84852891Sbostic 
84952891Sbostic 	if (vstate.off)
85052891Sbostic 		return;
85152891Sbostic 
85252891Sbostic 	/* save old color map entry zero */
85352891Sbostic 	bt459_select_reg(regs, 0);
85452891Sbostic 	vstate.color0[0] = regs->addr_cmap;
85552891Sbostic 	vstate.color0[1] = regs->addr_cmap;
85652891Sbostic 	vstate.color0[2] = regs->addr_cmap;
85752891Sbostic 
85852891Sbostic 	/* set color map entry zero to zero */
85952891Sbostic 	bt459_select_reg(regs, 0);
86052891Sbostic 	regs->addr_cmap = 0;
86152891Sbostic 	MachEmptyWriteBuffer();
86252891Sbostic 	regs->addr_cmap = 0;
86352891Sbostic 	MachEmptyWriteBuffer();
86452891Sbostic 	regs->addr_cmap = 0;
86552891Sbostic 	MachEmptyWriteBuffer();
86652891Sbostic 
86752891Sbostic 	/* disable display */
86852891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0);
86952891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0);
87052891Sbostic 
87152891Sbostic 	vstate.off = 1;
87252891Sbostic }
87356819Sralph 
87456819Sralph /*
87556819Sralph  * cfb keyboard and mouse input. Just punt to the generic ones in fb.c
87656819Sralph  */
87756819Sralph void
cfbKbdEvent(ch)87856819Sralph cfbKbdEvent(ch)
87956819Sralph 	int ch;
88056819Sralph {
88156819Sralph 	fbKbdEvent(ch, &cfbfb);
88256819Sralph }
88356819Sralph 
88456819Sralph void
cfbMouseEvent(newRepPtr)88556819Sralph cfbMouseEvent(newRepPtr)
88656819Sralph 	MouseReport *newRepPtr;
88756819Sralph {
88856819Sralph 	fbMouseEvent(newRepPtr, &cfbfb);
88956819Sralph }
89056819Sralph 
89156819Sralph void
cfbMouseButtons(newRepPtr)89256819Sralph cfbMouseButtons(newRepPtr)
89356819Sralph 	MouseReport *newRepPtr;
89456819Sralph {
89556819Sralph 	fbMouseButtons(newRepPtr, &cfbfb);
89656819Sralph }
89756819Sralph 
89856819Sralph /*
89956819Sralph  * Configure the mouse and keyboard based on machine type
90056819Sralph  */
90156819Sralph static void
cfbConfigMouse()90256819Sralph cfbConfigMouse()
90356819Sralph {
90456819Sralph 	int s;
90556819Sralph 
90656819Sralph 	s = spltty();
90756819Sralph 	switch (pmax_boardtype) {
90856819Sralph #if NDC > 0
90956819Sralph 	case DS_3MAX:
91056819Sralph 		dcDivertXInput = cfbKbdEvent;
91156819Sralph 		dcMouseEvent = cfbMouseEvent;
91256819Sralph 		dcMouseButtons = cfbMouseButtons;
91356819Sralph 		break;
91452891Sbostic #endif
91556819Sralph #if NSCC > 1
91656819Sralph 	case DS_3MIN:
91756819Sralph 		sccDivertXInput = cfbKbdEvent;
91856819Sralph 		sccMouseEvent = cfbMouseEvent;
91956819Sralph 		sccMouseButtons = cfbMouseButtons;
92056819Sralph 		break;
92156819Sralph #endif
92256819Sralph #if NDTOP > 0
92356819Sralph 	case DS_MAXINE:
92456819Sralph 		dtopDivertXInput = cfbKbdEvent;
92556819Sralph 		dtopMouseEvent = cfbMouseEvent;
92656819Sralph 		dtopMouseButtons = cfbMouseButtons;
92756819Sralph 		break;
92856819Sralph #endif
92956819Sralph 	default:
93056819Sralph 		printf("Can't configure mouse/keyboard\n");
93156819Sralph 	};
93256819Sralph 	splx(s);
93356819Sralph }
93456819Sralph 
93556819Sralph /*
93656819Sralph  * and deconfigure them
93756819Sralph  */
93856819Sralph static void
cfbDeconfigMouse()93956819Sralph cfbDeconfigMouse()
94056819Sralph {
94156819Sralph 	int s;
94256819Sralph 
94356819Sralph 	s = spltty();
94456819Sralph 	switch (pmax_boardtype) {
94556819Sralph #if NDC > 0
94656819Sralph 	case DS_3MAX:
94756819Sralph 		dcDivertXInput = (void (*)())0;
94856819Sralph 		dcMouseEvent = (void (*)())0;
94956819Sralph 		dcMouseButtons = (void (*)())0;
95056819Sralph 		break;
95156819Sralph #endif
95256819Sralph #if NSCC > 1
95356819Sralph 	case DS_3MIN:
95456819Sralph 		sccDivertXInput = (void (*)())0;
95556819Sralph 		sccMouseEvent = (void (*)())0;
95656819Sralph 		sccMouseButtons = (void (*)())0;
95756819Sralph 		break;
95856819Sralph #endif
95956819Sralph #if NDTOP > 0
96056819Sralph 	case DS_MAXINE:
96156819Sralph 		dtopDivertXInput = (void (*)())0;
96256819Sralph 		dtopMouseEvent = (void (*)())0;
96356819Sralph 		dtopMouseButtons = (void (*)())0;
96456819Sralph 		break;
96556819Sralph #endif
96656819Sralph 	default:
96756819Sralph 		printf("Can't deconfigure mouse/keyboard\n");
96856819Sralph 	};
96956819Sralph }
97056819Sralph #endif /* NCFB */
971