xref: /csrg-svn/sys/pmax/dev/cfb.c (revision 56525)
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
652891Sbostic  * Ralph Campbell.
752891Sbostic  *
852891Sbostic  * %sccs.include.redist.c%
952891Sbostic  *
10*56525Sbostic  *	@(#)cfb.c	7.4 (Berkeley) 10/11/92
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 
5552891Sbostic #include "cfb.h"
5652891Sbostic #if NCFB > 0
5752891Sbostic 
5852891Sbostic /*
5952891Sbostic  * This is a device driver for the PMAG-BA color frame buffer
6052891Sbostic  * on the TURBOchannel.
6152891Sbostic  * XXX This is just to get a console working;
6252891Sbostic  *	it will need changes to work with X11R5.
6352891Sbostic  */
6452891Sbostic 
6556522Sbostic #include <sys/param.h>
6656522Sbostic #include <sys/time.h>
6756522Sbostic #include <sys/kernel.h>
6856522Sbostic #include <sys/ioctl.h>
6956522Sbostic #include <sys/file.h>
7056522Sbostic #include <sys/errno.h>
7156522Sbostic #include <sys/proc.h>
7256522Sbostic #include <sys/mman.h>
7352891Sbostic 
7456522Sbostic #include <vm/vm.h>
7552891Sbostic 
7656522Sbostic #include <machine/machConst.h>
7756522Sbostic #include <machine/machMon.h>
7856522Sbostic #include <machine/dc7085cons.h>
7956522Sbostic #include <machine/pmioctl.h>
8052891Sbostic 
81*56525Sbostic #include <pmax/dev/device.h>
82*56525Sbostic #include <pmax/dev/cfbreg.h>
83*56525Sbostic #include <pmax/dev/font.c>
8456522Sbostic 
8552891Sbostic #define MAX_ROW	56
8652891Sbostic #define MAX_COL	80
8752891Sbostic 
8852891Sbostic /*
8952891Sbostic  * Macro to translate from a time struct to milliseconds.
9052891Sbostic  */
9152891Sbostic #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))
9252891Sbostic 
9352891Sbostic static int	isMono;		/* true if B&W frame buffer */
9452891Sbostic static int	initialized;	/* true if 'probe' was successful */
9552891Sbostic static int	GraphicsOpen;	/* true if the graphics device is open */
9652891Sbostic static int	row, col;	/* row and col for console cursor */
9752891Sbostic static struct	selinfo cfb_selp;	/* process waiting for select */
9852891Sbostic static unsigned	fb_addr;	/* frame buffer kernel virtual address */
9952891Sbostic static unsigned	planemask_addr;	/* plane mask kernel virtual address */
10052891Sbostic 
10152891Sbostic /*
10252891Sbostic  * These need to be mapped into user space.
10352891Sbostic  */
10452891Sbostic static struct pmuaccess {
10552891Sbostic 	PM_Info		scrInfo;
10652891Sbostic 	pmEvent		events[PM_MAXEVQ];
10752891Sbostic 	pmTimeCoord	tcs[MOTION_BUFFER_SIZE];
10852891Sbostic } pmu;
10952891Sbostic 
11052891Sbostic /*
11152891Sbostic  * Font mask bits used by Blitc().
11252891Sbostic  */
11352891Sbostic static unsigned int fontmaskBits[16] = {
11452891Sbostic 	0x00000000,
11552891Sbostic 	0x00000001,
11652891Sbostic 	0x00000100,
11752891Sbostic 	0x00000101,
11852891Sbostic 	0x00010000,
11952891Sbostic 	0x00010001,
12052891Sbostic 	0x00010100,
12152891Sbostic 	0x00010101,
12252891Sbostic 	0x01000000,
12352891Sbostic 	0x01000001,
12452891Sbostic 	0x01000100,
12552891Sbostic 	0x01000101,
12652891Sbostic 	0x01010000,
12752891Sbostic 	0x01010001,
12852891Sbostic 	0x01010100,
12952891Sbostic 	0x01010101
13052891Sbostic };
13152891Sbostic 
13252891Sbostic /*
13352891Sbostic  * Forward references.
13452891Sbostic  */
13552891Sbostic static void Scroll();
13652891Sbostic static void Blitc();
13752891Sbostic 
13852891Sbostic static void ScreenInit();
13952891Sbostic static void LoadCursor();
14052891Sbostic static void RestoreCursorColor();
14152891Sbostic static void CursorColor();
14252891Sbostic static void PosCursor();
14352891Sbostic static void InitColorMap();
14452891Sbostic static void LoadColorMap();
14552891Sbostic static void EnableVideo();
14652891Sbostic static void DisableVideo();
14752891Sbostic 
14852891Sbostic extern void dcKBDPutc();
14952891Sbostic extern void (*dcDivertXInput)();
15052891Sbostic extern void (*dcMouseEvent)();
15152891Sbostic extern void (*dcMouseButtons)();
15252891Sbostic 
15352891Sbostic int	cfbprobe();
15452891Sbostic struct	driver cfbdriver = {
15552891Sbostic 	"cfb", cfbprobe, 0, 0,
15652891Sbostic };
15752891Sbostic 
15852891Sbostic /*
15952891Sbostic  * Test to see if device is present.
16052891Sbostic  * Return true if found and initialized ok.
16152891Sbostic  */
16252891Sbostic cfbprobe(cp)
16352891Sbostic 	register struct pmax_ctlr *cp;
16452891Sbostic {
16552891Sbostic 
16652891Sbostic 	if (!initialized) {
16752891Sbostic 		if (!cfb_init(cp))
16852891Sbostic 			return (0);
16952891Sbostic 	}
17052891Sbostic 	printf("cfb%d at nexus0 csr 0x%x priority %d\n",
17152891Sbostic 		cp->pmax_unit, cp->pmax_addr, cp->pmax_pri);
17252891Sbostic 	return (1);
17352891Sbostic }
17452891Sbostic 
17552891Sbostic /*
17652891Sbostic  *----------------------------------------------------------------------
17752891Sbostic  *
17852891Sbostic  * cfbKbdEvent --
17952891Sbostic  *
18052891Sbostic  *	Process a received character.
18152891Sbostic  *
18252891Sbostic  * Results:
18352891Sbostic  *	None.
18452891Sbostic  *
18552891Sbostic  * Side effects:
18652891Sbostic  *	Events added to the queue.
18752891Sbostic  *
18852891Sbostic  *----------------------------------------------------------------------
18952891Sbostic  */
19052891Sbostic void
19152891Sbostic cfbKbdEvent(ch)
19252891Sbostic 	int ch;
19352891Sbostic {
19452891Sbostic 	register pmEvent *eventPtr;
19552891Sbostic 	int i;
19652891Sbostic 
19752891Sbostic 	if (!GraphicsOpen)
19852891Sbostic 		return;
19952891Sbostic 
20052891Sbostic 	/*
20152891Sbostic 	 * See if there is room in the queue.
20252891Sbostic 	 */
20352891Sbostic 	i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
20452891Sbostic 	if (i == pmu.scrInfo.qe.eHead)
20552891Sbostic 		return;
20652891Sbostic 
20752891Sbostic 	/*
20852891Sbostic 	 * Add the event to the queue.
20952891Sbostic 	 */
21052891Sbostic 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
21152891Sbostic 	eventPtr->type = BUTTON_RAW_TYPE;
21252891Sbostic 	eventPtr->device = KEYBOARD_DEVICE;
21352891Sbostic 	eventPtr->x = pmu.scrInfo.mouse.x;
21452891Sbostic 	eventPtr->y = pmu.scrInfo.mouse.y;
21552891Sbostic 	eventPtr->time = TO_MS(time);
21652891Sbostic 	eventPtr->key = ch;
21752891Sbostic 	pmu.scrInfo.qe.eTail = i;
21852891Sbostic 	selwakeup(&cfb_selp);
21952891Sbostic }
22052891Sbostic 
22152891Sbostic /*
22252891Sbostic  *----------------------------------------------------------------------
22352891Sbostic  *
22452891Sbostic  * cfbMouseEvent --
22552891Sbostic  *
22652891Sbostic  *	Process a mouse event.
22752891Sbostic  *
22852891Sbostic  * Results:
22952891Sbostic  *	None.
23052891Sbostic  *
23152891Sbostic  * Side effects:
23252891Sbostic  *	An event is added to the event queue.
23352891Sbostic  *
23452891Sbostic  *----------------------------------------------------------------------
23552891Sbostic  */
23652891Sbostic void
23752891Sbostic cfbMouseEvent(newRepPtr)
23852891Sbostic 	register MouseReport *newRepPtr;
23952891Sbostic {
24052891Sbostic 	unsigned milliSec;
24152891Sbostic 	int i;
24252891Sbostic 	pmEvent *eventPtr;
24352891Sbostic 
24452891Sbostic 	if (!GraphicsOpen)
24552891Sbostic 		return;
24652891Sbostic 
24752891Sbostic 	milliSec = TO_MS(time);
24852891Sbostic 
24952891Sbostic 	/*
25052891Sbostic 	 * Check to see if we have to accelerate the mouse
25152891Sbostic 	 */
25252891Sbostic 	if (pmu.scrInfo.mscale >= 0) {
25352891Sbostic 		if (newRepPtr->dx >= pmu.scrInfo.mthreshold) {
25452891Sbostic 			newRepPtr->dx +=
25552891Sbostic 				(newRepPtr->dx - pmu.scrInfo.mthreshold) *
25652891Sbostic 				pmu.scrInfo.mscale;
25752891Sbostic 		}
25852891Sbostic 		if (newRepPtr->dy >= pmu.scrInfo.mthreshold) {
25952891Sbostic 			newRepPtr->dy +=
26052891Sbostic 				(newRepPtr->dy - pmu.scrInfo.mthreshold) *
26152891Sbostic 				pmu.scrInfo.mscale;
26252891Sbostic 		}
26352891Sbostic 	}
26452891Sbostic 
26552891Sbostic 	/*
26652891Sbostic 	 * Update mouse position
26752891Sbostic 	 */
26852891Sbostic 	if (newRepPtr->state & MOUSE_X_SIGN) {
26952891Sbostic 		pmu.scrInfo.mouse.x += newRepPtr->dx;
27052891Sbostic 		if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x)
27152891Sbostic 			pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x;
27252891Sbostic 	} else {
27352891Sbostic 		pmu.scrInfo.mouse.x -= newRepPtr->dx;
27452891Sbostic 		if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x)
27552891Sbostic 			pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x;
27652891Sbostic 	}
27752891Sbostic 	if (newRepPtr->state & MOUSE_Y_SIGN) {
27852891Sbostic 		pmu.scrInfo.mouse.y -= newRepPtr->dy;
27952891Sbostic 		if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y)
28052891Sbostic 			pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y;
28152891Sbostic 	} else {
28252891Sbostic 		pmu.scrInfo.mouse.y += newRepPtr->dy;
28352891Sbostic 		if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y)
28452891Sbostic 			pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y;
28552891Sbostic 	}
28652891Sbostic 
28752891Sbostic 	/*
28852891Sbostic 	 * Move the hardware cursor.
28952891Sbostic 	 */
29052891Sbostic 	PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
29152891Sbostic 
29252891Sbostic 	/*
29352891Sbostic 	 * Store the motion event in the motion buffer.
29452891Sbostic 	 */
29552891Sbostic 	pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec;
29652891Sbostic 	pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x;
29752891Sbostic 	pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y;
29852891Sbostic 	if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
29952891Sbostic 		pmu.scrInfo.qe.tcNext = 0;
30052891Sbostic 	if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom &&
30152891Sbostic 	    pmu.scrInfo.mouse.y >=  pmu.scrInfo.mbox.top &&
30252891Sbostic 	    pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right &&
30352891Sbostic 	    pmu.scrInfo.mouse.x >=  pmu.scrInfo.mbox.left)
30452891Sbostic 		return;
30552891Sbostic 
30652891Sbostic 	pmu.scrInfo.mbox.bottom = 0;
30752891Sbostic 	if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead)
30852891Sbostic 		return;
30952891Sbostic 
31052891Sbostic 	i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1);
31152891Sbostic 	if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) &&
31252891Sbostic 	    (i != pmu.scrInfo.qe.eHead)) {
31352891Sbostic 		pmEvent *eventPtr;
31452891Sbostic 
31552891Sbostic 		eventPtr = &pmu.events[i];
31652891Sbostic 		if (eventPtr->type == MOTION_TYPE) {
31752891Sbostic 			eventPtr->x = pmu.scrInfo.mouse.x;
31852891Sbostic 			eventPtr->y = pmu.scrInfo.mouse.y;
31952891Sbostic 			eventPtr->time = milliSec;
32052891Sbostic 			eventPtr->device = MOUSE_DEVICE;
32152891Sbostic 			return;
32252891Sbostic 		}
32352891Sbostic 	}
32452891Sbostic 	/*
32552891Sbostic 	 * Put event into queue and wakeup any waiters.
32652891Sbostic 	 */
32752891Sbostic 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
32852891Sbostic 	eventPtr->type = MOTION_TYPE;
32952891Sbostic 	eventPtr->time = milliSec;
33052891Sbostic 	eventPtr->x = pmu.scrInfo.mouse.x;
33152891Sbostic 	eventPtr->y = pmu.scrInfo.mouse.y;
33252891Sbostic 	eventPtr->device = MOUSE_DEVICE;
33352891Sbostic 	pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
33452891Sbostic 	selwakeup(&cfb_selp);
33552891Sbostic }
33652891Sbostic 
33752891Sbostic /*
33852891Sbostic  *----------------------------------------------------------------------
33952891Sbostic  *
34052891Sbostic  * cfbMouseButtons --
34152891Sbostic  *
34252891Sbostic  *	Process mouse buttons.
34352891Sbostic  *
34452891Sbostic  * Results:
34552891Sbostic  *	None.
34652891Sbostic  *
34752891Sbostic  * Side effects:
34852891Sbostic  *	None.
34952891Sbostic  *
35052891Sbostic  *----------------------------------------------------------------------
35152891Sbostic  */
35252891Sbostic void
35352891Sbostic cfbMouseButtons(newRepPtr)
35452891Sbostic 	MouseReport *newRepPtr;
35552891Sbostic {
35652891Sbostic 	static char temp, oldSwitch, newSwitch;
35752891Sbostic 	int i, j;
35852891Sbostic 	pmEvent *eventPtr;
35952891Sbostic 	static MouseReport lastRep;
36052891Sbostic 
36152891Sbostic 	if (!GraphicsOpen)
36252891Sbostic 		return;
36352891Sbostic 
36452891Sbostic 	newSwitch = newRepPtr->state & 0x07;
36552891Sbostic 	oldSwitch = lastRep.state & 0x07;
36652891Sbostic 
36752891Sbostic 	temp = oldSwitch ^ newSwitch;
36852891Sbostic 	if (temp == 0)
36952891Sbostic 		return;
37052891Sbostic 	for (j = 1; j < 8; j <<= 1) {
37152891Sbostic 		if ((j & temp) == 0)
37252891Sbostic 			continue;
37352891Sbostic 
37452891Sbostic 		/*
37552891Sbostic 		 * Check for room in the queue
37652891Sbostic 		 */
37752891Sbostic 		i = PM_EVROUND(pmu.scrInfo.qe.eTail+1);
37852891Sbostic 		if (i == pmu.scrInfo.qe.eHead)
37952891Sbostic 			return;
38052891Sbostic 
38152891Sbostic 		/*
38252891Sbostic 		 * Put event into queue.
38352891Sbostic 		 */
38452891Sbostic 		eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
38552891Sbostic 
38652891Sbostic 		switch (j) {
38752891Sbostic 		case RIGHT_BUTTON:
38852891Sbostic 			eventPtr->key = EVENT_RIGHT_BUTTON;
38952891Sbostic 			break;
39052891Sbostic 
39152891Sbostic 		case MIDDLE_BUTTON:
39252891Sbostic 			eventPtr->key = EVENT_MIDDLE_BUTTON;
39352891Sbostic 			break;
39452891Sbostic 
39552891Sbostic 		case LEFT_BUTTON:
39652891Sbostic 			eventPtr->key = EVENT_LEFT_BUTTON;
39752891Sbostic 		}
39852891Sbostic 		if (newSwitch & j)
39952891Sbostic 			eventPtr->type = BUTTON_DOWN_TYPE;
40052891Sbostic 		else
40152891Sbostic 			eventPtr->type = BUTTON_UP_TYPE;
40252891Sbostic 		eventPtr->device = MOUSE_DEVICE;
40352891Sbostic 
40452891Sbostic 		eventPtr->time = TO_MS(time);
40552891Sbostic 		eventPtr->x = pmu.scrInfo.mouse.x;
40652891Sbostic 		eventPtr->y = pmu.scrInfo.mouse.y;
40752891Sbostic 	}
40852891Sbostic 	pmu.scrInfo.qe.eTail = i;
40952891Sbostic 	selwakeup(&cfb_selp);
41052891Sbostic 
41152891Sbostic 	lastRep = *newRepPtr;
41252891Sbostic 	pmu.scrInfo.mswitches = newSwitch;
41352891Sbostic }
41452891Sbostic 
41552891Sbostic /*
41652891Sbostic  *----------------------------------------------------------------------
41752891Sbostic  *
41852891Sbostic  * Scroll --
41952891Sbostic  *
42052891Sbostic  *	Scroll the screen.
42152891Sbostic  *
42252891Sbostic  * Results:
42352891Sbostic  *	None.
42452891Sbostic  *
42552891Sbostic  * Side effects:
42652891Sbostic  *	None.
42752891Sbostic  *
42852891Sbostic  *----------------------------------------------------------------------
42952891Sbostic  */
43052891Sbostic static void
43152891Sbostic Scroll()
43252891Sbostic {
43352891Sbostic 	register int *dest, *src;
43452891Sbostic 	register int *end;
43552891Sbostic 	register int temp0, temp1, temp2, temp3;
43652891Sbostic 	register int i, scanInc, lineCount;
43752891Sbostic 	int line;
43852891Sbostic 
43952891Sbostic 	/*
44052891Sbostic 	 * If the mouse is on we don't scroll so that the bit map remains sane.
44152891Sbostic 	 */
44252891Sbostic 	if (GraphicsOpen) {
44352891Sbostic 		row = 0;
44452891Sbostic 		return;
44552891Sbostic 	}
44652891Sbostic 
44752891Sbostic 	/*
44852891Sbostic 	 *  The following is an optimization to cause the scrolling
44952891Sbostic 	 *  of text to be memory limited.  Basically the writebuffer is
45052891Sbostic 	 *  4 words (32 bits ea.) long so to achieve maximum speed we
45152891Sbostic 	 *  read and write in multiples of 4 words. We also limit the
45252891Sbostic 	 *  size to be MAX_COL characters for more speed.
45352891Sbostic 	 */
45452891Sbostic 	if (isMono) {
45552891Sbostic 		lineCount = 5;
45652891Sbostic 		line = 1920 * 2;
45752891Sbostic 		scanInc = 44;
45852891Sbostic 	} else {
45952891Sbostic 		lineCount = 40;
46052891Sbostic 		scanInc = 96;
46152891Sbostic 		line = 1920 * 8;
46252891Sbostic 	}
46352891Sbostic 	src = (int *)(fb_addr + line);
46452891Sbostic 	dest = (int *)(fb_addr);
46552891Sbostic 	end = (int *)(fb_addr + (60 * line) - line);
46652891Sbostic 	do {
46752891Sbostic 		i = 0;
46852891Sbostic 		do {
46952891Sbostic 			temp0 = src[0];
47052891Sbostic 			temp1 = src[1];
47152891Sbostic 			temp2 = src[2];
47252891Sbostic 			temp3 = src[3];
47352891Sbostic 			dest[0] = temp0;
47452891Sbostic 			dest[1] = temp1;
47552891Sbostic 			dest[2] = temp2;
47652891Sbostic 			dest[3] = temp3;
47752891Sbostic 			dest += 4;
47852891Sbostic 			src += 4;
47952891Sbostic 			i++;
48052891Sbostic 		} while (i < lineCount);
48152891Sbostic 		src += scanInc;
48252891Sbostic 		dest += scanInc;
48352891Sbostic 	} while (src < end);
48452891Sbostic 
48552891Sbostic 	/*
48652891Sbostic 	 * Now zero out the last two lines
48752891Sbostic 	 */
48852891Sbostic 	bzero(fb_addr + (row * line), 3 * line);
48952891Sbostic }
49052891Sbostic 
49152891Sbostic /*
49252891Sbostic  *----------------------------------------------------------------------
49352891Sbostic  *
49452891Sbostic  * cfbPutc --
49552891Sbostic  *
49652891Sbostic  *	Write a character to the console.
49752891Sbostic  *
49852891Sbostic  * Results:
49952891Sbostic  *	None.
50052891Sbostic  *
50152891Sbostic  * Side effects:
50252891Sbostic  *	None.
50352891Sbostic  *
50452891Sbostic  *----------------------------------------------------------------------
50552891Sbostic  */
50652891Sbostic cfbPutc(c)
50752891Sbostic 	register int c;
50852891Sbostic {
50952891Sbostic 	int s;
51052891Sbostic 
51152891Sbostic 	s = splhigh();	/* in case we do any printf's at interrupt time */
51252891Sbostic 	if (initialized) {
51352891Sbostic #ifdef DEBUG
51452891Sbostic 		/*
51552891Sbostic 		 * If the HELP key is pressed, wait for another
51652891Sbostic 		 * HELP key press to start/stop output.
51752891Sbostic 		 */
51852891Sbostic 		if (dcDebugGetc() == LK_HELP) {
51952891Sbostic 			while (dcDebugGetc() != LK_HELP)
52052891Sbostic 				;
52152891Sbostic 		}
52252891Sbostic #endif
52352891Sbostic 		Blitc(c);
52452891Sbostic 	} else {
52552891Sbostic 		void (*f)() = (void (*)())MACH_MON_PUTCHAR;
52652891Sbostic 
52752891Sbostic 		(*f)(c);
52852891Sbostic 	}
52952891Sbostic 	splx(s);
53052891Sbostic }
53152891Sbostic 
53252891Sbostic /*
53352891Sbostic  *----------------------------------------------------------------------
53452891Sbostic  *
53552891Sbostic  * Blitc --
53652891Sbostic  *
53752891Sbostic  *	Write a character to the screen.
53852891Sbostic  *
53952891Sbostic  * Results:
54052891Sbostic  *	None.
54152891Sbostic  *
54252891Sbostic  * Side effects:
54352891Sbostic  *	None.
54452891Sbostic  *
54552891Sbostic  *----------------------------------------------------------------------
54652891Sbostic  */
54752891Sbostic static void
54852891Sbostic Blitc(c)
54952891Sbostic 	register int c;
55052891Sbostic {
55152891Sbostic 	register char *bRow, *fRow;
55252891Sbostic 	register int i;
55352891Sbostic 	register int ote = isMono ? 256 : 1024; /* offset to table entry */
55452891Sbostic 	int colMult = isMono ? 1 : 8;
55552891Sbostic 
55652891Sbostic 	c &= 0xff;
55752891Sbostic 
55852891Sbostic 	switch (c) {
55952891Sbostic 	case '\t':
56052891Sbostic 		for (i = 8 - (col & 0x7); i > 0; i--)
56152891Sbostic 			Blitc(' ');
56252891Sbostic 		break;
56352891Sbostic 
56452891Sbostic 	case '\r':
56552891Sbostic 		col = 0;
56652891Sbostic 		break;
56752891Sbostic 
56852891Sbostic 	case '\b':
56952891Sbostic 		col--;
57052891Sbostic 		if (col < 0)
57152891Sbostic 			col = 0;
57252891Sbostic 		break;
57352891Sbostic 
57452891Sbostic 	case '\n':
57552891Sbostic 		if (row + 1 >= MAX_ROW)
57652891Sbostic 			Scroll();
57752891Sbostic 		else
57852891Sbostic 			row++;
57952891Sbostic 		col = 0;
58052891Sbostic 		break;
58152891Sbostic 
58252891Sbostic 	case '\007':
58352891Sbostic 		dcKBDPutc(LK_RING_BELL);
58452891Sbostic 		break;
58552891Sbostic 
58652891Sbostic 	default:
58752891Sbostic 		/*
58852891Sbostic 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
58952891Sbostic 		 * support.
59052891Sbostic 		 */
59152891Sbostic 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
59252891Sbostic 			break;
59352891Sbostic 		/*
59452891Sbostic 		 * If the next character will wrap around then
59552891Sbostic 		 * increment row counter or scroll screen.
59652891Sbostic 		 */
59752891Sbostic 		if (col >= MAX_COL) {
59852891Sbostic 			col = 0;
59952891Sbostic 			if (row + 1 >= MAX_ROW)
60052891Sbostic 				Scroll();
60152891Sbostic 			else
60252891Sbostic 				row++;
60352891Sbostic 		}
60452891Sbostic 		bRow = (char *)(fb_addr +
60552891Sbostic 			(row * 15 & 0x3ff) * ote + col * colMult);
60652891Sbostic 		i = c - ' ';
60752891Sbostic 		/*
60852891Sbostic 		 * This is to skip the (32) 8-bit
60952891Sbostic 		 * control chars, as well as DEL
61052891Sbostic 		 * and 0xA0 which aren't printable
61152891Sbostic 		 */
61252891Sbostic 		if (c > '~')
61352891Sbostic 			i -= 34;
61452891Sbostic 		i *= 15;
61552891Sbostic 		fRow = (char *)((int)pmFont + i);
61652891Sbostic 
61752891Sbostic 		/* inline expansion for speed */
61852891Sbostic 		if (isMono) {
61952891Sbostic 			*bRow = *fRow++; bRow += ote;
62052891Sbostic 			*bRow = *fRow++; bRow += ote;
62152891Sbostic 			*bRow = *fRow++; bRow += ote;
62252891Sbostic 			*bRow = *fRow++; bRow += ote;
62352891Sbostic 			*bRow = *fRow++; bRow += ote;
62452891Sbostic 			*bRow = *fRow++; bRow += ote;
62552891Sbostic 			*bRow = *fRow++; bRow += ote;
62652891Sbostic 			*bRow = *fRow++; bRow += ote;
62752891Sbostic 			*bRow = *fRow++; bRow += ote;
62852891Sbostic 			*bRow = *fRow++; bRow += ote;
62952891Sbostic 			*bRow = *fRow++; bRow += ote;
63052891Sbostic 			*bRow = *fRow++; bRow += ote;
63152891Sbostic 			*bRow = *fRow++; bRow += ote;
63252891Sbostic 			*bRow = *fRow++; bRow += ote;
63352891Sbostic 			*bRow = *fRow++; bRow += ote;
63452891Sbostic 		} else {
63552891Sbostic 			register int j;
63652891Sbostic 			register unsigned int *pInt;
63752891Sbostic 
63852891Sbostic 			pInt = (unsigned int *)bRow;
63952891Sbostic 			for (j = 0; j < 15; j++) {
64052891Sbostic 				/*
64152891Sbostic 				 * fontmaskBits converts a nibble
64252891Sbostic 				 * (4 bytes) to a long word
64352891Sbostic 				 * containing 4 pixels corresponding
64452891Sbostic 				 * to each bit in the nibble.  Thus
64552891Sbostic 				 * we write two longwords for each
64652891Sbostic 				 * byte in font.
64752891Sbostic 				 *
64852891Sbostic 				 * Remember the font is 8 bits wide
64952891Sbostic 				 * and 15 bits high.
65052891Sbostic 				 *
65152891Sbostic 				 * We add 256 to the pointer to
65252891Sbostic 				 * point to the pixel on the
65352891Sbostic 				 * next scan line
65452891Sbostic 				 * directly below the current
65552891Sbostic 				 * pixel.
65652891Sbostic 				 */
65752891Sbostic 				pInt[0] = fontmaskBits[(*fRow) & 0xf];
65852891Sbostic 				pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
65952891Sbostic 				fRow++;
66052891Sbostic 				pInt += 256;
66152891Sbostic 			}
66252891Sbostic 		}
66352891Sbostic 		col++; /* increment column counter */
66452891Sbostic 	}
66552891Sbostic 	if (!GraphicsOpen)
66652891Sbostic 		PosCursor(col * 8, row * 15);
66752891Sbostic }
66852891Sbostic 
66952891Sbostic /*ARGSUSED*/
67052891Sbostic cfbopen(dev, flag)
67152891Sbostic 	dev_t dev;
67252891Sbostic 	int flag;
67352891Sbostic {
67452891Sbostic 
67552891Sbostic 	if (!initialized)
67652891Sbostic 		return (ENXIO);
67752891Sbostic 	if (GraphicsOpen)
67852891Sbostic 		return (EBUSY);
67952891Sbostic 
68052891Sbostic 	GraphicsOpen = 1;
68152891Sbostic 	if (!isMono)
68252891Sbostic 		InitColorMap();
68352891Sbostic 	/*
68452891Sbostic 	 * Set up event queue for later
68552891Sbostic 	 */
68652891Sbostic 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
68752891Sbostic 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
68852891Sbostic 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
68952891Sbostic 	pmu.scrInfo.qe.tcNext = 0;
69052891Sbostic 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
69152891Sbostic 	return (0);
69252891Sbostic }
69352891Sbostic 
69452891Sbostic /*ARGSUSED*/
69552891Sbostic cfbclose(dev, flag)
69652891Sbostic 	dev_t dev;
69752891Sbostic 	int flag;
69852891Sbostic {
69952959Sralph 	int s;
70052891Sbostic 
70152891Sbostic 	if (!GraphicsOpen)
70252891Sbostic 		return (EBADF);
70352891Sbostic 
70452891Sbostic 	GraphicsOpen = 0;
70552891Sbostic 	if (!isMono)
70652891Sbostic 		InitColorMap();
70752959Sralph 	s = spltty();
70852959Sralph 	dcDivertXInput = (void (*)())0;
70952959Sralph 	dcMouseEvent = (void (*)())0;
71052959Sralph 	dcMouseButtons = (void (*)())0;
71152959Sralph 	splx(s);
71252891Sbostic 	ScreenInit();
71352891Sbostic 	vmUserUnmap();
71452891Sbostic 	bzero(fb_addr, (isMono ? 1024 / 8 : 1024) * 864);
71552891Sbostic 	PosCursor(col * 8, row * 15);
71652891Sbostic 	return (0);
71752891Sbostic }
71852891Sbostic 
71952891Sbostic /*ARGSUSED*/
72052891Sbostic cfbioctl(dev, cmd, data, flag)
72152891Sbostic 	dev_t dev;
72252891Sbostic 	caddr_t data;
72352891Sbostic {
72452959Sralph 	int s;
72552891Sbostic 
72652891Sbostic 	switch (cmd) {
72752891Sbostic 	case QIOCGINFO:
72852891Sbostic 	    {
72952891Sbostic 		caddr_t addr;
73052891Sbostic 		extern caddr_t vmUserMap();
73152891Sbostic 
73252891Sbostic 		/*
73352891Sbostic 		 * Map the all the data the user needs access to into
73452891Sbostic 		 * user space.
73552891Sbostic 		 */
73652891Sbostic 		addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
73752891Sbostic 		if (addr == (caddr_t)0)
73852891Sbostic 			goto mapError;
73952891Sbostic 		*(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
74052891Sbostic 		pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
74152891Sbostic 		pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
74252891Sbostic 		/*
74352891Sbostic 		 * Map the plane mask into the user's address space.
74452891Sbostic 		 */
74552891Sbostic 		addr = vmUserMap(4, planemask_addr);
74652891Sbostic 		if (addr == (caddr_t)0)
74752891Sbostic 			goto mapError;
74852891Sbostic 		pmu.scrInfo.planemask = (char *)addr;
74952891Sbostic 		/*
75052891Sbostic 		 * Map the frame buffer into the user's address space.
75152891Sbostic 		 */
75252891Sbostic 		addr = vmUserMap(isMono ? 256*1024 : 1024*1024, fb_addr);
75352891Sbostic 		if (addr == (caddr_t)0)
75452891Sbostic 			goto mapError;
75552891Sbostic 		pmu.scrInfo.bitmap = (char *)addr;
75652891Sbostic 		break;
75752891Sbostic 
75852891Sbostic 	mapError:
75952891Sbostic 		vmUserUnmap();
76052891Sbostic 		printf("Cannot map shared data structures\n");
76152891Sbostic 		return (EIO);
76252891Sbostic 	    }
76352891Sbostic 
76452891Sbostic 	case QIOCPMSTATE:
76552891Sbostic 		/*
76652891Sbostic 		 * Set mouse state.
76752891Sbostic 		 */
76852891Sbostic 		pmu.scrInfo.mouse = *(pmCursor *)data;
76952891Sbostic 		PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
77052891Sbostic 		break;
77152891Sbostic 
77252891Sbostic 	case QIOCINIT:
77352891Sbostic 		/*
77452891Sbostic 		 * Initialize the screen.
77552891Sbostic 		 */
77652891Sbostic 		ScreenInit();
77752891Sbostic 		break;
77852891Sbostic 
77952891Sbostic 	case QIOCKPCMD:
78052891Sbostic 	    {
78152891Sbostic 		pmKpCmd *kpCmdPtr;
78252891Sbostic 		unsigned char *cp;
78352891Sbostic 
78452891Sbostic 		kpCmdPtr = (pmKpCmd *)data;
78552891Sbostic 		if (kpCmdPtr->nbytes == 0)
78652891Sbostic 			kpCmdPtr->cmd |= 0x80;
78752891Sbostic 		if (!GraphicsOpen)
78852891Sbostic 			kpCmdPtr->cmd |= 1;
78952891Sbostic 		dcKBDPutc((int)kpCmdPtr->cmd);
79052891Sbostic 		cp = &kpCmdPtr->par[0];
79152891Sbostic 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
79252891Sbostic 			if (kpCmdPtr->nbytes == 1)
79352891Sbostic 				*cp |= 0x80;
79452891Sbostic 			dcKBDPutc((int)*cp);
79552891Sbostic 		}
79652891Sbostic 		break;
79752891Sbostic 	    }
79852891Sbostic 
79952891Sbostic 	case QIOCADDR:
80052891Sbostic 		*(PM_Info **)data = &pmu.scrInfo;
80152891Sbostic 		break;
80252891Sbostic 
80352891Sbostic 	case QIOWCURSOR:
80452891Sbostic 		LoadCursor((unsigned short *)data);
80552891Sbostic 		break;
80652891Sbostic 
80752891Sbostic 	case QIOWCURSORCOLOR:
80852891Sbostic 		CursorColor((unsigned int *)data);
80952891Sbostic 		break;
81052891Sbostic 
81152891Sbostic 	case QIOSETCMAP:
81252891Sbostic 		LoadColorMap((ColorMap *)data);
81352891Sbostic 		break;
81452891Sbostic 
81552891Sbostic 	case QIOKERNLOOP:
81652959Sralph 		s = spltty();
81752891Sbostic 		dcDivertXInput = cfbKbdEvent;
81852891Sbostic 		dcMouseEvent = cfbMouseEvent;
81952891Sbostic 		dcMouseButtons = cfbMouseButtons;
82052959Sralph 		splx(s);
82152891Sbostic 		break;
82252891Sbostic 
82352891Sbostic 	case QIOKERNUNLOOP:
82452959Sralph 		s = spltty();
82552891Sbostic 		dcDivertXInput = (void (*)())0;
82652891Sbostic 		dcMouseEvent = (void (*)())0;
82752891Sbostic 		dcMouseButtons = (void (*)())0;
82852959Sralph 		splx(s);
82952891Sbostic 		break;
83052891Sbostic 
83152891Sbostic 	case QIOVIDEOON:
83252891Sbostic 		EnableVideo();
83352891Sbostic 		break;
83452891Sbostic 
83552891Sbostic 	case QIOVIDEOOFF:
83652891Sbostic 		DisableVideo();
83752891Sbostic 		break;
83852891Sbostic 
83952891Sbostic 	default:
84052891Sbostic 		printf("cfb0: Unknown ioctl command %x\n", cmd);
84152891Sbostic 		return (EINVAL);
84252891Sbostic 	}
84352891Sbostic 	return (0);
84452891Sbostic }
84552891Sbostic 
84652891Sbostic cfbselect(dev, flag, p)
84752891Sbostic 	dev_t dev;
84852891Sbostic 	int flag;
84952891Sbostic 	struct proc *p;
85052891Sbostic {
85152891Sbostic 
85252891Sbostic 	switch (flag) {
85352891Sbostic 	case FREAD:
85452891Sbostic 		if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
85552891Sbostic 			return (1);
85652891Sbostic 		selrecord(p, &cfb_selp);
85752891Sbostic 		break;
85852891Sbostic 	}
85952891Sbostic 
86052891Sbostic 	return (0);
86152891Sbostic }
86252891Sbostic 
86352891Sbostic static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
86452891Sbostic 
86552891Sbostic /*
86652891Sbostic  * The default cursor.
86752891Sbostic  */
86852891Sbostic static unsigned short defCursor[1024] = {
86952891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87052891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87152891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87252891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87352891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87452891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87552891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87652891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87752891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87852891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
87952891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88052891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88152891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88252891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88352891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88452891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88552891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88652891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88752891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88852891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88952891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89052891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89152891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89252891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89352891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89452891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89552891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89652891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89752891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89852891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89952891Sbostic 	0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
90052891Sbostic 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
90152891Sbostic };
90252891Sbostic 
90352891Sbostic #define	CFB_OFFSET_VRAM		0x0		/* from module's base */
90452891Sbostic 						/* Replicated at x100000 */
90552891Sbostic #define CFB_OFFSET_BT459	0x200000	/* Bt459 registers */
90652891Sbostic #define CFB_OFFSET_IREQ		0x300000	/* Interrupt req. control */
90752891Sbostic #define CFB_OFFSET_ROM		0x380000	/* Diagnostic ROM */
90852891Sbostic #define CFB_OFFSET_RESET	0x3c0000	/* Bt459 resets on writes */
90952891Sbostic 
91052891Sbostic /*
91152891Sbostic  * Generic register access
91252891Sbostic  */
91352891Sbostic void
91452891Sbostic bt459_select_reg(regs, regno)
91552891Sbostic 	bt459_regmap_t *regs;
91652891Sbostic {
91752891Sbostic 	regs->addr_lo = regno;
91852891Sbostic 	regs->addr_hi = regno >> 8;
91952891Sbostic 	MachEmptyWriteBuffer();
92052891Sbostic }
92152891Sbostic 
92252891Sbostic void
92352891Sbostic bt459_write_reg(regs, regno, val)
92452891Sbostic 	bt459_regmap_t *regs;
92552891Sbostic {
92652891Sbostic 	regs->addr_lo = regno;
92752891Sbostic 	regs->addr_hi = regno >> 8;
92852891Sbostic 	MachEmptyWriteBuffer();
92952891Sbostic 	regs->addr_reg = val;
93052891Sbostic 	MachEmptyWriteBuffer();
93152891Sbostic }
93252891Sbostic 
93352891Sbostic unsigned char
93452891Sbostic bt459_read_reg(regs, regno)
93552891Sbostic 	bt459_regmap_t *regs;
93652891Sbostic {
93752891Sbostic 	regs->addr_lo = regno;
93852891Sbostic 	regs->addr_hi = regno >> 8;
93952891Sbostic 	MachEmptyWriteBuffer();
94052891Sbostic 	return regs->addr_reg;
94152891Sbostic }
94252891Sbostic 
94352891Sbostic #ifdef DEBUG
94452891Sbostic bt459_print_colormap(regs)
94552891Sbostic 	bt459_regmap_t *regs;
94652891Sbostic {
94752891Sbostic 	register int i;
94852891Sbostic 
94952891Sbostic 	bt459_select_reg(regs, 0);
95052891Sbostic 	for (i = 0; i < 256; i++) {
95152891Sbostic 		register unsigned red, green, blue;
95252891Sbostic 
95352891Sbostic 		red = regs->addr_cmap;
95452891Sbostic 		green = regs->addr_cmap;
95552891Sbostic 		blue = regs->addr_cmap;
95652891Sbostic 		printf("%x->[x%x x%x x%x]\n", i, red, green, blue);
95752891Sbostic 	}
95852891Sbostic }
95952891Sbostic #endif
96052891Sbostic 
96152891Sbostic /*
96252891Sbostic  * Test to see if device is present.
96352891Sbostic  * Return true if found and initialized ok.
96452891Sbostic  */
96552891Sbostic cfb_init(cp)
96652891Sbostic 	register struct pmax_ctlr *cp;
96752891Sbostic {
96852891Sbostic 	bt459_regmap_t *regs;
96952891Sbostic 
97052891Sbostic 	/* check for no frame buffer */
97152891Sbostic 	if (badaddr(cp->pmax_addr, 4))
97252891Sbostic 		return (0);
97352891Sbostic 
97452891Sbostic 	fb_addr = (unsigned)cp->pmax_addr + CFB_OFFSET_VRAM;
97552891Sbostic 	planemask_addr = 0; /* XXX */
97652891Sbostic 	regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
97752891Sbostic 
97852891Sbostic 	if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
97952891Sbostic 		return (0);
98052891Sbostic 
98152891Sbostic 	*(int *)(fb_addr + CFB_OFFSET_RESET) = 0;	/* force chip reset */
98252891Sbostic 	DELAY(2000);	/* ???? check right time on specs! ???? */
98352891Sbostic 
98452891Sbostic 	/* use 4:1 input mux */
98552891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD0, 0x40);
98652891Sbostic 
98752891Sbostic 	/* no zooming, no panning */
98852891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD1, 0x00);
98952891Sbostic 
99052891Sbostic 	/*
99152891Sbostic 	 * signature test, X-windows cursor, no overlays, SYNC* PLL,
99252891Sbostic 	 * normal RAM select, 7.5 IRE pedestal, do sync
99352891Sbostic 	 */
99452891Sbostic 	bt459_write_reg(regs, BT459_REG_CMD2, 0xc2);
99552891Sbostic 
99652891Sbostic 	/* get all pixel bits */
99752891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
99852891Sbostic 
99952891Sbostic 	/* no blinking */
100052891Sbostic 	bt459_write_reg(regs, BT459_REG_PBM, 0x00);
100152891Sbostic 
100252891Sbostic 	/* no overlay */
100352891Sbostic 	bt459_write_reg(regs, BT459_REG_ORM, 0x00);
100452891Sbostic 
100552891Sbostic 	/* no overlay blink */
100652891Sbostic 	bt459_write_reg(regs, BT459_REG_OBM, 0x00);
100752891Sbostic 
100852891Sbostic 	/* no interleave, no underlay */
100952891Sbostic 	bt459_write_reg(regs, BT459_REG_ILV, 0x00);
101052891Sbostic 
101152891Sbostic 	/* normal operation, no signature analysis */
101252891Sbostic 	bt459_write_reg(regs, BT459_REG_TEST, 0x00);
101352891Sbostic 
101452891Sbostic 	/*
101552891Sbostic 	 * no blinking, 1bit cross hair, XOR reg&crosshair,
101652891Sbostic 	 * no crosshair on either plane 0 or 1,
101752891Sbostic 	 * regular cursor on both planes.
101852891Sbostic 	 */
101952891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
102052891Sbostic 
102152891Sbostic 	/* home cursor */
102252891Sbostic 	bt459_write_reg(regs, BT459_REG_CXLO, 0x00);
102352891Sbostic 	bt459_write_reg(regs, BT459_REG_CXHI, 0x00);
102452891Sbostic 	bt459_write_reg(regs, BT459_REG_CYLO, 0x00);
102552891Sbostic 	bt459_write_reg(regs, BT459_REG_CYHI, 0x00);
102652891Sbostic 
102752891Sbostic 	/* no crosshair window */
102852891Sbostic 	bt459_write_reg(regs, BT459_REG_WXLO, 0x00);
102952891Sbostic 	bt459_write_reg(regs, BT459_REG_WXHI, 0x00);
103052891Sbostic 	bt459_write_reg(regs, BT459_REG_WYLO, 0x00);
103152891Sbostic 	bt459_write_reg(regs, BT459_REG_WYHI, 0x00);
103252891Sbostic 	bt459_write_reg(regs, BT459_REG_WWLO, 0x00);
103352891Sbostic 	bt459_write_reg(regs, BT459_REG_WWHI, 0x00);
103452891Sbostic 	bt459_write_reg(regs, BT459_REG_WHLO, 0x00);
103552891Sbostic 	bt459_write_reg(regs, BT459_REG_WHHI, 0x00);
103652891Sbostic 
103752891Sbostic 	/*
103852891Sbostic 	 * Initialize screen info.
103952891Sbostic 	 */
104052891Sbostic 	pmu.scrInfo.max_row = MAX_ROW;
104152891Sbostic 	pmu.scrInfo.max_col = MAX_COL;
104252891Sbostic 	pmu.scrInfo.max_x = 1024;
104352891Sbostic 	pmu.scrInfo.max_y = 864;
104452891Sbostic 	pmu.scrInfo.max_cur_x = 1023;
104552891Sbostic 	pmu.scrInfo.max_cur_y = 863;
104652891Sbostic 	pmu.scrInfo.version = 11;
104752891Sbostic 	pmu.scrInfo.mthreshold = 4;
104852891Sbostic 	pmu.scrInfo.mscale = 2;
104952891Sbostic 	pmu.scrInfo.min_cur_x = 0;
105052891Sbostic 	pmu.scrInfo.min_cur_y = 0;
105152891Sbostic 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
105252891Sbostic 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
105352891Sbostic 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
105452891Sbostic 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
105552891Sbostic 	pmu.scrInfo.qe.tcNext = 0;
105652891Sbostic 
105752891Sbostic 	/*
105852891Sbostic 	 * Initialize the color map, the screen, and the mouse.
105952891Sbostic 	 */
106052891Sbostic 	InitColorMap();
106152891Sbostic 	ScreenInit();
106252891Sbostic 	Scroll();
106352891Sbostic 
106452891Sbostic 	initialized = 1;
106552891Sbostic 	return (1);
106652891Sbostic }
106752891Sbostic 
106852891Sbostic /*
106952891Sbostic  * ----------------------------------------------------------------------------
107052891Sbostic  *
107152891Sbostic  * ScreenInit --
107252891Sbostic  *
107352891Sbostic  *	Initialize the screen.
107452891Sbostic  *
107552891Sbostic  * Results:
107652891Sbostic  *	None.
107752891Sbostic  *
107852891Sbostic  * Side effects:
107952891Sbostic  *	The screen is initialized.
108052891Sbostic  *
108152891Sbostic  * ----------------------------------------------------------------------------
108252891Sbostic  */
108352891Sbostic static void
108452891Sbostic ScreenInit()
108552891Sbostic {
108652891Sbostic 
108752891Sbostic 	/*
108852891Sbostic 	 * Home the cursor.
108952891Sbostic 	 * We want an LSI terminal emulation. We want the graphics
109052891Sbostic 	 * terminal to scroll from the bottom. So start at the bottom.
109152891Sbostic 	 */
109252891Sbostic 	row = 55;
109352891Sbostic 	col = 0;
109452891Sbostic 
109552891Sbostic 	/*
109652891Sbostic 	 * Load the cursor with the default values
109752891Sbostic 	 *
109852891Sbostic 	 */
109952891Sbostic 	LoadCursor(defCursor);
110052891Sbostic }
110152891Sbostic 
110252891Sbostic /*
110352891Sbostic  * ----------------------------------------------------------------------------
110452891Sbostic  *
110552891Sbostic  * LoadCursor --
110652891Sbostic  *
110752891Sbostic  *	Routine to load the cursor Sprite pattern.
110852891Sbostic  *
110952891Sbostic  * Results:
111052891Sbostic  *	None.
111152891Sbostic  *
111252891Sbostic  * Side effects:
111352891Sbostic  *	The cursor is loaded into the hardware cursor.
111452891Sbostic  *
111552891Sbostic  * ----------------------------------------------------------------------------
111652891Sbostic  */
111752891Sbostic static void
111852891Sbostic LoadCursor(cur)
111952891Sbostic 	unsigned short *cur;
112052891Sbostic {
112152891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
112252891Sbostic 	register int i, j;
112352891Sbostic 
112452891Sbostic 	/*
112552891Sbostic 	 * As per specs, must run a check to see if we
112652891Sbostic 	 * had contention. If so, re-write the cursor.
112752891Sbostic 	 */
112852891Sbostic 	for (j = 0; j < 2; j++) {
112952891Sbostic 		/* loop once to write */
113052891Sbostic 		bt459_select_reg(regs, BT459_REG_CRAM_BASE);
113152891Sbostic 		for (i = 0; i < 1024; i++) {
113252891Sbostic 			regs->addr_reg = cur[i];
113352891Sbostic 			MachEmptyWriteBuffer();
113452891Sbostic 		}
113552891Sbostic 
113652891Sbostic 		/* loop to check, if fail write again */
113752891Sbostic 		bt459_select_reg(regs, BT459_REG_CRAM_BASE);
113852891Sbostic 		for (i = 0; i < 1024; i++)
113952891Sbostic 			if (regs->addr_reg != cur[i])
114052891Sbostic 				break;
114152891Sbostic 		if (i == 1024)
114252891Sbostic 			break;	/* all went well first shot */
114352891Sbostic 	}
114452891Sbostic }
114552891Sbostic 
114652891Sbostic /*
114752891Sbostic  * ----------------------------------------------------------------------------
114852891Sbostic  *
114952891Sbostic  * RestoreCursorColor --
115052891Sbostic  *
115152891Sbostic  *	Routine to restore the color of the cursor.
115252891Sbostic  *
115352891Sbostic  * Results:
115452891Sbostic  *	None.
115552891Sbostic  *
115652891Sbostic  * Side effects:
115752891Sbostic  *	None.
115852891Sbostic  *
115952891Sbostic  * ----------------------------------------------------------------------------
116052891Sbostic  */
116152891Sbostic static void
116252891Sbostic RestoreCursorColor()
116352891Sbostic {
116452891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
116552891Sbostic 	register int i;
116652891Sbostic 
116752891Sbostic 	bt459_select_reg(regs, BT459_REG_CCOLOR_2);
116852891Sbostic 	for (i = 0; i < 6; i++) {
116952891Sbostic 		regs->addr_reg = cursor_RGB[i];
117052891Sbostic 		MachEmptyWriteBuffer();
117152891Sbostic 	}
117252891Sbostic }
117352891Sbostic 
117452891Sbostic /*
117552891Sbostic  * ----------------------------------------------------------------------------
117652891Sbostic  *
117752891Sbostic  * CursorColor --
117852891Sbostic  *
117952891Sbostic  *	Set the color of the cursor.
118052891Sbostic  *
118152891Sbostic  * Results:
118252891Sbostic  *	None.
118352891Sbostic  *
118452891Sbostic  * Side effects:
118552891Sbostic  *	None.
118652891Sbostic  *
118752891Sbostic  * ----------------------------------------------------------------------------
118852891Sbostic  */
118952891Sbostic static void
119052891Sbostic CursorColor(color)
119152891Sbostic 	unsigned int color[];
119252891Sbostic {
119352891Sbostic 	register int i, j;
119452891Sbostic 
119552891Sbostic 	for (i = 0; i < 6; i++)
119652891Sbostic 		cursor_RGB[i] = (u_char)(color[i] >> 8);
119752891Sbostic 
119852891Sbostic 	RestoreCursorColor();
119952891Sbostic }
120052891Sbostic 
120152891Sbostic /*
120252891Sbostic  *----------------------------------------------------------------------
120352891Sbostic  *
120452891Sbostic  * PosCursor --
120552891Sbostic  *
120652891Sbostic  *	Postion the cursor.
120752891Sbostic  *
120852891Sbostic  * Results:
120952891Sbostic  *	None.
121052891Sbostic  *
121152891Sbostic  * Side effects:
121252891Sbostic  *	None.
121352891Sbostic  *
121452891Sbostic  *----------------------------------------------------------------------
121552891Sbostic  */
121652891Sbostic static void
121752891Sbostic PosCursor(x, y)
121852891Sbostic 	register int x, y;
121952891Sbostic {
122052891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
122152891Sbostic 
122252891Sbostic 	if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
122352891Sbostic 		y = pmu.scrInfo.max_cur_y;
122452891Sbostic 	if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
122552891Sbostic 		x = pmu.scrInfo.max_cur_x;
122652891Sbostic 	pmu.scrInfo.cursor.x = x;		/* keep track of real cursor */
122752891Sbostic 	pmu.scrInfo.cursor.y = y;		/* position, indep. of mouse */
122852891Sbostic 
122952891Sbostic 	x += 219;
123052891Sbostic 	y += 34;
123152891Sbostic 
123252891Sbostic 	bt459_select_reg(regs, BT459_REG_CXLO);
123352891Sbostic 	regs->addr_reg = x;
123452891Sbostic 	MachEmptyWriteBuffer();
123552891Sbostic 	regs->addr_reg = x >> 8;
123652891Sbostic 	MachEmptyWriteBuffer();
123752891Sbostic 	regs->addr_reg = y;
123852891Sbostic 	MachEmptyWriteBuffer();
123952891Sbostic 	regs->addr_reg = y >> 8;
124052891Sbostic 	MachEmptyWriteBuffer();
124152891Sbostic }
124252891Sbostic 
124352891Sbostic /*
124452891Sbostic  * ----------------------------------------------------------------------------
124552891Sbostic  *
124652891Sbostic  * InitColorMap --
124752891Sbostic  *
124852891Sbostic  *	Initialize the color map.
124952891Sbostic  *
125052891Sbostic  * Results:
125152891Sbostic  *	None.
125252891Sbostic  *
125352891Sbostic  * Side effects:
125452891Sbostic  *	The colormap is initialized appropriately.
125552891Sbostic  *
125652891Sbostic  * ----------------------------------------------------------------------------
125752891Sbostic  */
125852891Sbostic static void
125952891Sbostic InitColorMap()
126052891Sbostic {
126152891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
126252891Sbostic 	register int i;
126352891Sbostic 
126452891Sbostic 	bt459_select_reg(regs, 0);
126552891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
126652891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
126752891Sbostic 	regs->addr_cmap = 0; MachEmptyWriteBuffer();
126852891Sbostic 
126952891Sbostic 	for (i = 1; i < 256; i++) {
127052891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
127152891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
127252891Sbostic 		regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
127352891Sbostic 	}
127452891Sbostic 
127552891Sbostic 	for (i = 0; i < 3; i++) {
127652891Sbostic 		cursor_RGB[i] = 0x00;
127752891Sbostic 		cursor_RGB[i + 3] = 0xff;
127852891Sbostic 	}
127952891Sbostic 	RestoreCursorColor();
128052891Sbostic }
128152891Sbostic 
128252891Sbostic /*
128352891Sbostic  * ----------------------------------------------------------------------------
128452891Sbostic  *
128552891Sbostic  * LoadColorMap --
128652891Sbostic  *
128752891Sbostic  *	Load the color map.
128852891Sbostic  *
128952891Sbostic  * Results:
129052891Sbostic  *	None.
129152891Sbostic  *
129252891Sbostic  * Side effects:
129352891Sbostic  *	The color map is loaded.
129452891Sbostic  *
129552891Sbostic  * ----------------------------------------------------------------------------
129652891Sbostic  */
129752891Sbostic static void
129852891Sbostic LoadColorMap(ptr)
129952891Sbostic 	ColorMap *ptr;
130052891Sbostic {
130152891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
130252891Sbostic 
130352891Sbostic 	if (ptr->index > 256)
130452891Sbostic 		return;
130552891Sbostic 
130652891Sbostic 	bt459_select_reg(regs, ptr->index);
130752891Sbostic 
130852891Sbostic 	regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer();
130952891Sbostic 	regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer();
131052891Sbostic 	regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer();
131152891Sbostic }
131252891Sbostic 
131352891Sbostic /*
131452891Sbostic  * Video on/off state.
131552891Sbostic  */
131652891Sbostic struct vstate {
131752891Sbostic 	u_char	color0[3];	/* saved color map entry zero */
131852891Sbostic 	u_char	off;		/* TRUE if display is off */
131952891Sbostic } vstate;
132052891Sbostic 
132152891Sbostic /*
132252891Sbostic  * ----------------------------------------------------------------------------
132352891Sbostic  *
132452891Sbostic  * EnableVideo --
132552891Sbostic  *
132652891Sbostic  *	Enable the video display.
132752891Sbostic  *
132852891Sbostic  * Results:
132952891Sbostic  *	None.
133052891Sbostic  *
133152891Sbostic  * Side effects:
133252891Sbostic  *	The display is enabled.
133352891Sbostic  *
133452891Sbostic  * ----------------------------------------------------------------------------
133552891Sbostic  */
133652891Sbostic static void
133752891Sbostic EnableVideo()
133852891Sbostic {
133952891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
134052891Sbostic 
134152891Sbostic 	if (!vstate.off)
134252891Sbostic 		return;
134352891Sbostic 
134452891Sbostic 	/* restore old color map entry zero */
134552891Sbostic 	bt459_select_reg(regs, 0);
134652891Sbostic 	regs->addr_cmap = vstate.color0[0];
134752891Sbostic 	MachEmptyWriteBuffer();
134852891Sbostic 	regs->addr_cmap = vstate.color0[1];
134952891Sbostic 	MachEmptyWriteBuffer();
135052891Sbostic 	regs->addr_cmap = vstate.color0[2];
135152891Sbostic 	MachEmptyWriteBuffer();
135252891Sbostic 
135352891Sbostic 	/* enable normal display */
135452891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0xff);
135552891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
135652891Sbostic 
135752891Sbostic 	vstate.off = 0;
135852891Sbostic }
135952891Sbostic 
136052891Sbostic /*
136152891Sbostic  * ----------------------------------------------------------------------------
136252891Sbostic  *
136352891Sbostic  * DisableVideo --
136452891Sbostic  *
136552891Sbostic  *	Disable the video display.
136652891Sbostic  *
136752891Sbostic  * Results:
136852891Sbostic  *	None.
136952891Sbostic  *
137052891Sbostic  * Side effects:
137152891Sbostic  *	The display is disabled.
137252891Sbostic  *
137352891Sbostic  * ----------------------------------------------------------------------------
137452891Sbostic  */
137552891Sbostic static void
137652891Sbostic DisableVideo()
137752891Sbostic {
137852891Sbostic 	bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459);
137952891Sbostic 
138052891Sbostic 	if (vstate.off)
138152891Sbostic 		return;
138252891Sbostic 
138352891Sbostic 	/* save old color map entry zero */
138452891Sbostic 	bt459_select_reg(regs, 0);
138552891Sbostic 	vstate.color0[0] = regs->addr_cmap;
138652891Sbostic 	vstate.color0[1] = regs->addr_cmap;
138752891Sbostic 	vstate.color0[2] = regs->addr_cmap;
138852891Sbostic 
138952891Sbostic 	/* set color map entry zero to zero */
139052891Sbostic 	bt459_select_reg(regs, 0);
139152891Sbostic 	regs->addr_cmap = 0;
139252891Sbostic 	MachEmptyWriteBuffer();
139352891Sbostic 	regs->addr_cmap = 0;
139452891Sbostic 	MachEmptyWriteBuffer();
139552891Sbostic 	regs->addr_cmap = 0;
139652891Sbostic 	MachEmptyWriteBuffer();
139752891Sbostic 
139852891Sbostic 	/* disable display */
139952891Sbostic 	bt459_write_reg(regs, BT459_REG_PRM, 0);
140052891Sbostic 	bt459_write_reg(regs, BT459_REG_CCR, 0);
140152891Sbostic 
140252891Sbostic 	vstate.off = 1;
140352891Sbostic }
140452891Sbostic #endif
1405