xref: /csrg-svn/sys/pmax/dev/pm.c (revision 56525)
152130Smckusick /*
252130Smckusick  * Copyright (c) 1992 Regents of the University of California.
352130Smckusick  * All rights reserved.
452130Smckusick  *
552130Smckusick  * This code is derived from software contributed to Berkeley by
652130Smckusick  * Ralph Campbell.
752130Smckusick  *
852130Smckusick  * %sccs.include.redist.c%
952130Smckusick  *
10*56525Sbostic  *	@(#)pm.c	7.7 (Berkeley) 10/11/92
1152130Smckusick  *
1252130Smckusick  *  devGraphics.c --
1352130Smckusick  *
1452130Smckusick  *     	This file contains machine-dependent routines for the graphics device.
1552130Smckusick  *
1652130Smckusick  *	Copyright (C) 1989 Digital Equipment Corporation.
1752130Smckusick  *	Permission to use, copy, modify, and distribute this software and
1852130Smckusick  *	its documentation for any purpose and without fee is hereby granted,
1952130Smckusick  *	provided that the above copyright notice appears in all copies.
2052130Smckusick  *	Digital Equipment Corporation makes no representations about the
2152130Smckusick  *	suitability of this software for any purpose.  It is provided "as is"
2252130Smckusick  *	without express or implied warranty.
2352130Smckusick  *
2452130Smckusick  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
2552130Smckusick  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
2652130Smckusick  */
2752130Smckusick 
2852130Smckusick #include "pm.h"
2952130Smckusick #if NPM > 0
3052130Smckusick 
3156522Sbostic #include <sys/param.h>
3256522Sbostic #include <sys/time.h>
3356522Sbostic #include <sys/kernel.h>
3456522Sbostic #include <sys/ioctl.h>
3556522Sbostic #include <sys/file.h>
3656522Sbostic #include <sys/errno.h>
3756522Sbostic #include <sys/proc.h>
3856522Sbostic #include <sys/mman.h>
3952130Smckusick 
4056522Sbostic #include <vm/vm.h>
4152130Smckusick 
4256522Sbostic #include <machine/machConst.h>
4356522Sbostic #include <machine/machMon.h>
4456522Sbostic #include <machine/dc7085cons.h>
4556522Sbostic #include <machine/pmioctl.h>
4652130Smckusick 
47*56525Sbostic #include <pmax/dev/device.h>
48*56525Sbostic #include <pmax/dev/pmreg.h>
49*56525Sbostic #include <pmax/dev/font.c>
5056522Sbostic 
5152862Sralph #define MAX_ROW	56
5252862Sralph #define MAX_COL	80
5352862Sralph 
5452130Smckusick /*
5552130Smckusick  * Macro to translate from a time struct to milliseconds.
5652130Smckusick  */
5752130Smckusick #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))
5852130Smckusick 
5952130Smckusick static u_short	curReg;		/* copy of PCCRegs.cmdr since it's read only */
6052130Smckusick static int	isMono;		/* true if B&W frame buffer */
6152130Smckusick static int	initialized;	/* true if 'probe' was successful */
6252130Smckusick static int	GraphicsOpen;	/* true if the graphics device is open */
6352862Sralph static int	row, col;	/* row and col for console cursor */
6452675Smckusick static struct	selinfo pm_selp;/* process waiting for select */
6552130Smckusick 
6652130Smckusick /*
6752130Smckusick  * These need to be mapped into user space.
6852130Smckusick  */
6952130Smckusick static struct pmuaccess {
7052130Smckusick 	PM_Info		scrInfo;
7152130Smckusick 	pmEvent		events[PM_MAXEVQ];
7252130Smckusick 	pmTimeCoord	tcs[MOTION_BUFFER_SIZE];
7352130Smckusick } pmu;
7452130Smckusick 
7552130Smckusick /*
7652130Smckusick  * Font mask bits used by Blitc().
7752130Smckusick  */
7852130Smckusick static unsigned int fontmaskBits[16] = {
7952130Smckusick 	0x00000000,
8052130Smckusick 	0x00000001,
8152130Smckusick 	0x00000100,
8252130Smckusick 	0x00000101,
8352130Smckusick 	0x00010000,
8452130Smckusick 	0x00010001,
8552130Smckusick 	0x00010100,
8652130Smckusick 	0x00010101,
8752130Smckusick 	0x01000000,
8852130Smckusick 	0x01000001,
8952130Smckusick 	0x01000100,
9052130Smckusick 	0x01000101,
9152130Smckusick 	0x01010000,
9252130Smckusick 	0x01010001,
9352130Smckusick 	0x01010100,
9452130Smckusick 	0x01010101
9552130Smckusick };
9652130Smckusick 
9752130Smckusick /*
9852130Smckusick  * Forward references.
9952130Smckusick  */
10052862Sralph static void Scroll();
10152862Sralph static void Blitc();
10252862Sralph 
10352130Smckusick static void ScreenInit();
10452130Smckusick static void LoadCursor();
10552130Smckusick static void RestoreCursorColor();
10652130Smckusick static void CursorColor();
10752862Sralph static void PosCursor();
10852130Smckusick static void InitColorMap();
10952130Smckusick static void VDACInit();
11052130Smckusick static void LoadColorMap();
11152862Sralph static void EnableVideo();
11252862Sralph static void DisableVideo();
11352130Smckusick 
11452130Smckusick extern void dcKBDPutc();
11552862Sralph extern void (*dcDivertXInput)();
11652862Sralph extern void (*dcMouseEvent)();
11752862Sralph extern void (*dcMouseButtons)();
11852130Smckusick 
11952130Smckusick int	pmprobe();
12052130Smckusick struct	driver pmdriver = {
12152130Smckusick 	"pm", pmprobe, 0, 0,
12252130Smckusick };
12352130Smckusick 
12452130Smckusick /*
12552130Smckusick  * Test to see if device is present.
12652130Smckusick  * Return true if found and initialized ok.
12752130Smckusick  */
12852130Smckusick /*ARGSUSED*/
12952130Smckusick pmprobe(cp)
13052130Smckusick 	register struct pmax_ctlr *cp;
13152130Smckusick {
13252130Smckusick 
13352130Smckusick 	if (!initialized && !pminit())
13452130Smckusick 		return (0);
13552130Smckusick 	if (isMono)
13652130Smckusick 		printf("pm0 (monochrome display)\n");
13752130Smckusick 	else
13852130Smckusick 		printf("pm0 (color display)\n");
13952130Smckusick 	return (1);
14052130Smckusick }
14152130Smckusick 
14252130Smckusick /*
14352130Smckusick  *----------------------------------------------------------------------
14452130Smckusick  *
14552130Smckusick  * pmKbdEvent --
14652130Smckusick  *
14752130Smckusick  *	Process a received character.
14852130Smckusick  *
14952130Smckusick  * Results:
15052130Smckusick  *	None.
15152130Smckusick  *
15252130Smckusick  * Side effects:
15352130Smckusick  *	Events added to the queue.
15452130Smckusick  *
15552130Smckusick  *----------------------------------------------------------------------
15652130Smckusick  */
15752130Smckusick void
15852130Smckusick pmKbdEvent(ch)
15952130Smckusick 	int ch;
16052130Smckusick {
16152130Smckusick 	register pmEvent *eventPtr;
16252130Smckusick 	int i;
16352130Smckusick 
16452130Smckusick 	if (!GraphicsOpen)
16552130Smckusick 		return;
16652130Smckusick 
16752130Smckusick 	/*
16852130Smckusick 	 * See if there is room in the queue.
16952130Smckusick 	 */
17052130Smckusick 	i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
17152130Smckusick 	if (i == pmu.scrInfo.qe.eHead)
17252130Smckusick 		return;
17352130Smckusick 
17452130Smckusick 	/*
17552130Smckusick 	 * Add the event to the queue.
17652130Smckusick 	 */
17752130Smckusick 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
17852130Smckusick 	eventPtr->type = BUTTON_RAW_TYPE;
17952130Smckusick 	eventPtr->device = KEYBOARD_DEVICE;
18052130Smckusick 	eventPtr->x = pmu.scrInfo.mouse.x;
18152130Smckusick 	eventPtr->y = pmu.scrInfo.mouse.y;
18252130Smckusick 	eventPtr->time = TO_MS(time);
18352130Smckusick 	eventPtr->key = ch;
18452130Smckusick 	pmu.scrInfo.qe.eTail = i;
18552675Smckusick 	selwakeup(&pm_selp);
18652130Smckusick }
18752130Smckusick 
18852130Smckusick /*
18952130Smckusick  *----------------------------------------------------------------------
19052130Smckusick  *
19152130Smckusick  * pmMouseEvent --
19252130Smckusick  *
19352130Smckusick  *	Process a mouse event.
19452130Smckusick  *
19552130Smckusick  * Results:
19652130Smckusick  *	None.
19752130Smckusick  *
19852130Smckusick  * Side effects:
19952130Smckusick  *	An event is added to the event queue.
20052130Smckusick  *
20152130Smckusick  *----------------------------------------------------------------------
20252130Smckusick  */
20352130Smckusick void
20452130Smckusick pmMouseEvent(newRepPtr)
20552130Smckusick 	register MouseReport *newRepPtr;
20652130Smckusick {
20752130Smckusick 	unsigned milliSec;
20852130Smckusick 	int i;
20952130Smckusick 	pmEvent *eventPtr;
21052130Smckusick 
21152130Smckusick 	if (!GraphicsOpen)
21252130Smckusick 		return;
21352130Smckusick 
21452130Smckusick 	milliSec = TO_MS(time);
21552130Smckusick 
21652130Smckusick 	/*
21752130Smckusick 	 * Check to see if we have to accelerate the mouse
21852130Smckusick 	 */
21952130Smckusick 	if (pmu.scrInfo.mscale >= 0) {
22052130Smckusick 		if (newRepPtr->dx >= pmu.scrInfo.mthreshold) {
22152130Smckusick 			newRepPtr->dx +=
22252130Smckusick 				(newRepPtr->dx - pmu.scrInfo.mthreshold) *
22352130Smckusick 				pmu.scrInfo.mscale;
22452130Smckusick 		}
22552130Smckusick 		if (newRepPtr->dy >= pmu.scrInfo.mthreshold) {
22652130Smckusick 			newRepPtr->dy +=
22752130Smckusick 				(newRepPtr->dy - pmu.scrInfo.mthreshold) *
22852130Smckusick 				pmu.scrInfo.mscale;
22952130Smckusick 		}
23052130Smckusick 	}
23152130Smckusick 
23252130Smckusick 	/*
23352130Smckusick 	 * Update mouse position
23452130Smckusick 	 */
23552130Smckusick 	if (newRepPtr->state & MOUSE_X_SIGN) {
23652130Smckusick 		pmu.scrInfo.mouse.x += newRepPtr->dx;
23752130Smckusick 		if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x)
23852130Smckusick 			pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x;
23952130Smckusick 	} else {
24052130Smckusick 		pmu.scrInfo.mouse.x -= newRepPtr->dx;
24152130Smckusick 		if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x)
24252130Smckusick 			pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x;
24352130Smckusick 	}
24452130Smckusick 	if (newRepPtr->state & MOUSE_Y_SIGN) {
24552130Smckusick 		pmu.scrInfo.mouse.y -= newRepPtr->dy;
24652130Smckusick 		if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y)
24752130Smckusick 			pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y;
24852130Smckusick 	} else {
24952130Smckusick 		pmu.scrInfo.mouse.y += newRepPtr->dy;
25052130Smckusick 		if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y)
25152130Smckusick 			pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y;
25252130Smckusick 	}
25352130Smckusick 
25452130Smckusick 	/*
25552130Smckusick 	 * Move the hardware cursor.
25652130Smckusick 	 */
25752130Smckusick 	PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
25852130Smckusick 
25952130Smckusick 	/*
26052130Smckusick 	 * Store the motion event in the motion buffer.
26152130Smckusick 	 */
26252130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec;
26352130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x;
26452130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y;
26552130Smckusick 	if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
26652130Smckusick 		pmu.scrInfo.qe.tcNext = 0;
26752130Smckusick 	if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom &&
26852130Smckusick 	    pmu.scrInfo.mouse.y >=  pmu.scrInfo.mbox.top &&
26952130Smckusick 	    pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right &&
27052130Smckusick 	    pmu.scrInfo.mouse.x >=  pmu.scrInfo.mbox.left)
27152130Smckusick 		return;
27252130Smckusick 
27352130Smckusick 	pmu.scrInfo.mbox.bottom = 0;
27452130Smckusick 	if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead)
27552130Smckusick 		return;
27652130Smckusick 
27752130Smckusick 	i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1);
27852130Smckusick 	if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) &&
27952130Smckusick 	    (i != pmu.scrInfo.qe.eHead)) {
28052130Smckusick 		pmEvent *eventPtr;
28152130Smckusick 
28252130Smckusick 		eventPtr = &pmu.events[i];
28352130Smckusick 		if (eventPtr->type == MOTION_TYPE) {
28452130Smckusick 			eventPtr->x = pmu.scrInfo.mouse.x;
28552130Smckusick 			eventPtr->y = pmu.scrInfo.mouse.y;
28652130Smckusick 			eventPtr->time = milliSec;
28752130Smckusick 			eventPtr->device = MOUSE_DEVICE;
28852130Smckusick 			return;
28952130Smckusick 		}
29052130Smckusick 	}
29152130Smckusick 	/*
29252130Smckusick 	 * Put event into queue and wakeup any waiters.
29352130Smckusick 	 */
29452130Smckusick 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
29552130Smckusick 	eventPtr->type = MOTION_TYPE;
29652130Smckusick 	eventPtr->time = milliSec;
29752130Smckusick 	eventPtr->x = pmu.scrInfo.mouse.x;
29852130Smckusick 	eventPtr->y = pmu.scrInfo.mouse.y;
29952130Smckusick 	eventPtr->device = MOUSE_DEVICE;
30052130Smckusick 	pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
30152675Smckusick 	selwakeup(&pm_selp);
30252130Smckusick }
30352130Smckusick 
30452130Smckusick /*
30552130Smckusick  *----------------------------------------------------------------------
30652130Smckusick  *
30752130Smckusick  * pmMouseButtons --
30852130Smckusick  *
30952130Smckusick  *	Process mouse buttons.
31052130Smckusick  *
31152130Smckusick  * Results:
31252130Smckusick  *	None.
31352130Smckusick  *
31452130Smckusick  * Side effects:
31552130Smckusick  *	None.
31652130Smckusick  *
31752130Smckusick  *----------------------------------------------------------------------
31852130Smckusick  */
31952130Smckusick void
32052130Smckusick pmMouseButtons(newRepPtr)
32152130Smckusick 	MouseReport *newRepPtr;
32252130Smckusick {
32352130Smckusick 	static char temp, oldSwitch, newSwitch;
32452130Smckusick 	int i, j;
32552130Smckusick 	pmEvent *eventPtr;
32652130Smckusick 	static MouseReport lastRep;
32752130Smckusick 
32852130Smckusick 	if (!GraphicsOpen)
32952130Smckusick 		return;
33052130Smckusick 
33152130Smckusick 	newSwitch = newRepPtr->state & 0x07;
33252130Smckusick 	oldSwitch = lastRep.state & 0x07;
33352130Smckusick 
33452130Smckusick 	temp = oldSwitch ^ newSwitch;
33552130Smckusick 	if (temp == 0)
33652130Smckusick 		return;
33752130Smckusick 	for (j = 1; j < 8; j <<= 1) {
33852130Smckusick 		if ((j & temp) == 0)
33952130Smckusick 			continue;
34052130Smckusick 
34152130Smckusick 		/*
34252130Smckusick 		 * Check for room in the queue
34352130Smckusick 		 */
34452130Smckusick 		i = PM_EVROUND(pmu.scrInfo.qe.eTail+1);
34552130Smckusick 		if (i == pmu.scrInfo.qe.eHead)
34652130Smckusick 			return;
34752130Smckusick 
34852130Smckusick 		/*
34952130Smckusick 		 * Put event into queue.
35052130Smckusick 		 */
35152130Smckusick 		eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
35252130Smckusick 
35352130Smckusick 		switch (j) {
35452130Smckusick 		case RIGHT_BUTTON:
35552130Smckusick 			eventPtr->key = EVENT_RIGHT_BUTTON;
35652130Smckusick 			break;
35752130Smckusick 
35852130Smckusick 		case MIDDLE_BUTTON:
35952130Smckusick 			eventPtr->key = EVENT_MIDDLE_BUTTON;
36052130Smckusick 			break;
36152130Smckusick 
36252130Smckusick 		case LEFT_BUTTON:
36352130Smckusick 			eventPtr->key = EVENT_LEFT_BUTTON;
36452130Smckusick 		}
36552130Smckusick 		if (newSwitch & j)
36652130Smckusick 			eventPtr->type = BUTTON_DOWN_TYPE;
36752130Smckusick 		else
36852130Smckusick 			eventPtr->type = BUTTON_UP_TYPE;
36952130Smckusick 		eventPtr->device = MOUSE_DEVICE;
37052130Smckusick 
37152130Smckusick 		eventPtr->time = TO_MS(time);
37252130Smckusick 		eventPtr->x = pmu.scrInfo.mouse.x;
37352130Smckusick 		eventPtr->y = pmu.scrInfo.mouse.y;
37452130Smckusick 	}
37552130Smckusick 	pmu.scrInfo.qe.eTail = i;
37652675Smckusick 	selwakeup(&pm_selp);
37752130Smckusick 
37852130Smckusick 	lastRep = *newRepPtr;
37952130Smckusick 	pmu.scrInfo.mswitches = newSwitch;
38052130Smckusick }
38152130Smckusick 
38252130Smckusick /*
38352130Smckusick  *----------------------------------------------------------------------
38452130Smckusick  *
38552130Smckusick  * Scroll --
38652130Smckusick  *
38752130Smckusick  *	Scroll the screen.
38852130Smckusick  *
38952130Smckusick  * Results:
39052130Smckusick  *	None.
39152130Smckusick  *
39252130Smckusick  * Side effects:
39352130Smckusick  *	None.
39452130Smckusick  *
39552130Smckusick  *----------------------------------------------------------------------
39652130Smckusick  */
39752130Smckusick static void
39852130Smckusick Scroll()
39952130Smckusick {
40052130Smckusick 	register int *dest, *src;
40152130Smckusick 	register int *end;
40252130Smckusick 	register int temp0, temp1, temp2, temp3;
40352130Smckusick 	register int i, scanInc, lineCount;
40452130Smckusick 	int line;
40552130Smckusick 
40652130Smckusick 	/*
40752130Smckusick 	 * If the mouse is on we don't scroll so that the bit map remains sane.
40852130Smckusick 	 */
40952130Smckusick 	if (GraphicsOpen) {
41052862Sralph 		row = 0;
41152130Smckusick 		return;
41252130Smckusick 	}
41352130Smckusick 
41452130Smckusick 	/*
41552130Smckusick 	 *  The following is an optimization to cause the scrolling
41652130Smckusick 	 *  of text to be memory limited.  Basically the writebuffer is
41752130Smckusick 	 *  4 words (32 bits ea.) long so to achieve maximum speed we
41852130Smckusick 	 *  read and write in multiples of 4 words. We also limit the
41952862Sralph 	 *  size to be MAX_COL characters for more speed.
42052130Smckusick 	 */
42152130Smckusick 	if (isMono) {
42252130Smckusick 		lineCount = 5;
42352130Smckusick 		line = 1920 * 2;
42452130Smckusick 		scanInc = 44;
42552130Smckusick 	} else {
42652130Smckusick 		lineCount = 40;
42752130Smckusick 		scanInc = 96;
42852130Smckusick 		line = 1920 * 8;
42952130Smckusick 	}
43052130Smckusick 	src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line);
43152130Smckusick 	dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR);
43252130Smckusick 	end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line);
43352130Smckusick 	do {
43452130Smckusick 		i = 0;
43552130Smckusick 		do {
43652130Smckusick 			temp0 = src[0];
43752130Smckusick 			temp1 = src[1];
43852130Smckusick 			temp2 = src[2];
43952130Smckusick 			temp3 = src[3];
44052130Smckusick 			dest[0] = temp0;
44152130Smckusick 			dest[1] = temp1;
44252130Smckusick 			dest[2] = temp2;
44352130Smckusick 			dest[3] = temp3;
44452130Smckusick 			dest += 4;
44552130Smckusick 			src += 4;
44652130Smckusick 			i++;
44752130Smckusick 		} while (i < lineCount);
44852130Smckusick 		src += scanInc;
44952130Smckusick 		dest += scanInc;
45052130Smckusick 	} while (src < end);
45152130Smckusick 
45252130Smckusick 	/*
45352130Smckusick 	 * Now zero out the last two lines
45452130Smckusick 	 */
45552862Sralph 	bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (row * line), 3 * line);
45652130Smckusick }
45752130Smckusick 
45852130Smckusick /*
45952130Smckusick  *----------------------------------------------------------------------
46052130Smckusick  *
46152130Smckusick  * pmPutc --
46252130Smckusick  *
46352130Smckusick  *	Write a character to the console.
46452130Smckusick  *
46552130Smckusick  * Results:
46652130Smckusick  *	None.
46752130Smckusick  *
46852130Smckusick  * Side effects:
46952130Smckusick  *	None.
47052130Smckusick  *
47152130Smckusick  *----------------------------------------------------------------------
47252130Smckusick  */
47352130Smckusick pmPutc(c)
47452130Smckusick 	register int c;
47552130Smckusick {
47652130Smckusick 	int s;
47752130Smckusick 
47852130Smckusick 	s = splhigh();	/* in case we do any printf's at interrupt time */
47952130Smckusick 	if (initialized) {
48052130Smckusick #ifdef DEBUG
48152130Smckusick 		/*
48252130Smckusick 		 * If the HELP key is pressed, wait for another
48352130Smckusick 		 * HELP key press to start/stop output.
48452130Smckusick 		 */
48552862Sralph 		if (dcDebugGetc() == LK_HELP) {
48652862Sralph 			while (dcDebugGetc() != LK_HELP)
48752130Smckusick 				;
48852130Smckusick 		}
48952130Smckusick #endif
49052130Smckusick 		Blitc(c);
49152130Smckusick 	} else {
49252130Smckusick 		void (*f)() = (void (*)())MACH_MON_PUTCHAR;
49352130Smckusick 
49452130Smckusick 		(*f)(c);
49552130Smckusick 	}
49652130Smckusick 	splx(s);
49752130Smckusick }
49852130Smckusick 
49952130Smckusick /*
50052130Smckusick  *----------------------------------------------------------------------
50152130Smckusick  *
50252130Smckusick  * Blitc --
50352130Smckusick  *
50452130Smckusick  *	Write a character to the screen.
50552130Smckusick  *
50652130Smckusick  * Results:
50752130Smckusick  *	None.
50852130Smckusick  *
50952130Smckusick  * Side effects:
51052130Smckusick  *	None.
51152130Smckusick  *
51252130Smckusick  *----------------------------------------------------------------------
51352130Smckusick  */
51452130Smckusick static void
51552130Smckusick Blitc(c)
51652130Smckusick 	register int c;
51752130Smckusick {
51852130Smckusick 	register char *bRow, *fRow;
51952130Smckusick 	register int i;
52052130Smckusick 	register int ote = isMono ? 256 : 1024; /* offset to table entry */
52152130Smckusick 	int colMult = isMono ? 1 : 8;
52252130Smckusick 
52352130Smckusick 	c &= 0xff;
52452130Smckusick 
52552130Smckusick 	switch (c) {
52652130Smckusick 	case '\t':
52752862Sralph 		for (i = 8 - (col & 0x7); i > 0; i--)
52852130Smckusick 			Blitc(' ');
52952130Smckusick 		break;
53052130Smckusick 
53152130Smckusick 	case '\r':
53252862Sralph 		col = 0;
53352130Smckusick 		break;
53452130Smckusick 
53552130Smckusick 	case '\b':
53652862Sralph 		col--;
53752862Sralph 		if (col < 0)
53852862Sralph 			col = 0;
53952130Smckusick 		break;
54052130Smckusick 
54152130Smckusick 	case '\n':
54252862Sralph 		if (row + 1 >= MAX_ROW)
54352130Smckusick 			Scroll();
54452130Smckusick 		else
54552862Sralph 			row++;
54652862Sralph 		col = 0;
54752130Smckusick 		break;
54852130Smckusick 
54952130Smckusick 	case '\007':
55052130Smckusick 		dcKBDPutc(LK_RING_BELL);
55152130Smckusick 		break;
55252130Smckusick 
55352130Smckusick 	default:
55452130Smckusick 		/*
55552862Sralph 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
55652862Sralph 		 * support.
55752862Sralph 		 */
55852862Sralph 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
55952862Sralph 			break;
56052862Sralph 		/*
56152130Smckusick 		 * If the next character will wrap around then
56252130Smckusick 		 * increment row counter or scroll screen.
56352130Smckusick 		 */
56452862Sralph 		if (col >= MAX_COL) {
56552862Sralph 			col = 0;
56652862Sralph 			if (row + 1 >= MAX_ROW)
56752130Smckusick 				Scroll();
56852130Smckusick 			else
56952862Sralph 				row++;
57052130Smckusick 		}
57152130Smckusick 		bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR +
57252862Sralph 			(row * 15 & 0x3ff) * ote + col * colMult);
57352130Smckusick 		i = c - ' ';
57452130Smckusick 		/*
57552130Smckusick 		 * This is to skip the (32) 8-bit
57652130Smckusick 		 * control chars, as well as DEL
57752130Smckusick 		 * and 0xA0 which aren't printable
57852130Smckusick 		 */
57952130Smckusick 		if (c > '~')
58052130Smckusick 			i -= 34;
58152130Smckusick 		i *= 15;
58252130Smckusick 		fRow = (char *)((int)pmFont + i);
58352130Smckusick 
58452130Smckusick 		/* inline expansion for speed */
58552130Smckusick 		if (isMono) {
58652130Smckusick 			*bRow = *fRow++; bRow += ote;
58752130Smckusick 			*bRow = *fRow++; bRow += ote;
58852130Smckusick 			*bRow = *fRow++; bRow += ote;
58952130Smckusick 			*bRow = *fRow++; bRow += ote;
59052130Smckusick 			*bRow = *fRow++; bRow += ote;
59152130Smckusick 			*bRow = *fRow++; bRow += ote;
59252130Smckusick 			*bRow = *fRow++; bRow += ote;
59352130Smckusick 			*bRow = *fRow++; bRow += ote;
59452130Smckusick 			*bRow = *fRow++; bRow += ote;
59552130Smckusick 			*bRow = *fRow++; bRow += ote;
59652130Smckusick 			*bRow = *fRow++; bRow += ote;
59752130Smckusick 			*bRow = *fRow++; bRow += ote;
59852130Smckusick 			*bRow = *fRow++; bRow += ote;
59952130Smckusick 			*bRow = *fRow++; bRow += ote;
60052130Smckusick 			*bRow = *fRow++; bRow += ote;
60152130Smckusick 		} else {
60252130Smckusick 			register int j;
60352130Smckusick 			register unsigned int *pInt;
60452130Smckusick 
60552130Smckusick 			pInt = (unsigned int *)bRow;
60652130Smckusick 			for (j = 0; j < 15; j++) {
60752130Smckusick 				/*
60852130Smckusick 				 * fontmaskBits converts a nibble
60952130Smckusick 				 * (4 bytes) to a long word
61052130Smckusick 				 * containing 4 pixels corresponding
61152130Smckusick 				 * to each bit in the nibble.  Thus
61252130Smckusick 				 * we write two longwords for each
61352130Smckusick 				 * byte in font.
61452130Smckusick 				 *
61552130Smckusick 				 * Remember the font is 8 bits wide
61652130Smckusick 				 * and 15 bits high.
61752130Smckusick 				 *
61852130Smckusick 				 * We add 256 to the pointer to
61952130Smckusick 				 * point to the pixel on the
62052130Smckusick 				 * next scan line
62152130Smckusick 				 * directly below the current
62252130Smckusick 				 * pixel.
62352130Smckusick 				 */
62452130Smckusick 				pInt[0] = fontmaskBits[(*fRow) & 0xf];
62552130Smckusick 				pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
62652130Smckusick 				fRow++;
62752130Smckusick 				pInt += 256;
62852130Smckusick 			}
62952130Smckusick 		}
63052862Sralph 		col++; /* increment column counter */
63152130Smckusick 	}
63252130Smckusick 	if (!GraphicsOpen)
63352862Sralph 		PosCursor(col * 8, row * 15);
63452130Smckusick }
63552130Smckusick 
63652130Smckusick /*ARGSUSED*/
63752130Smckusick pmopen(dev, flag)
63852130Smckusick 	dev_t dev;
63952130Smckusick 	int flag;
64052130Smckusick {
64153823Smckusick 	int s;
64252130Smckusick 
64352130Smckusick 	if (!initialized)
64452130Smckusick 		return (ENXIO);
64552130Smckusick 	if (GraphicsOpen)
64652130Smckusick 		return (EBUSY);
64752130Smckusick 
64852130Smckusick 	GraphicsOpen = 1;
64952130Smckusick 	if (!isMono)
65052130Smckusick 		InitColorMap();
65152130Smckusick 	/*
65252130Smckusick 	 * Set up event queue for later
65352130Smckusick 	 */
65452130Smckusick 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
65552130Smckusick 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
65652130Smckusick 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
65752130Smckusick 	pmu.scrInfo.qe.tcNext = 0;
65852130Smckusick 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
65953823Smckusick 	s = spltty();
66053823Smckusick 	dcDivertXInput = pmKbdEvent;
66153823Smckusick 	dcMouseEvent = pmMouseEvent;
66253823Smckusick 	dcMouseButtons = pmMouseButtons;
66353823Smckusick 	splx(s);
66452130Smckusick 	return (0);
66552130Smckusick }
66652130Smckusick 
66752130Smckusick /*ARGSUSED*/
66852130Smckusick pmclose(dev, flag)
66952130Smckusick 	dev_t dev;
67052130Smckusick 	int flag;
67152130Smckusick {
67252960Sralph 	int s;
67352130Smckusick 
67452130Smckusick 	if (!GraphicsOpen)
67552130Smckusick 		return (EBADF);
67652130Smckusick 
67752130Smckusick 	GraphicsOpen = 0;
67852130Smckusick 	if (!isMono)
67952130Smckusick 		InitColorMap();
68052960Sralph 	s = spltty();
68152960Sralph 	dcDivertXInput = (void (*)())0;
68252960Sralph 	dcMouseEvent = (void (*)())0;
68352960Sralph 	dcMouseButtons = (void (*)())0;
68452960Sralph 	splx(s);
68552130Smckusick 	ScreenInit();
68652130Smckusick 	vmUserUnmap();
68752862Sralph 	bzero((caddr_t)MACH_UNCACHED_FRAME_BUFFER_ADDR,
68852862Sralph 		(isMono ? 1024 / 8 : 1024) * 864);
68952862Sralph 	PosCursor(col * 8, row * 15);
69052130Smckusick 	return (0);
69152130Smckusick }
69252130Smckusick 
69352130Smckusick /*ARGSUSED*/
69452130Smckusick pmioctl(dev, cmd, data, flag)
69552130Smckusick 	dev_t dev;
69652130Smckusick 	caddr_t data;
69752130Smckusick {
69852130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
69952960Sralph 	int s;
70052130Smckusick 
70152130Smckusick 	switch (cmd) {
70252130Smckusick 	case QIOCGINFO:
70352130Smckusick 	    {
70452130Smckusick 		caddr_t addr;
70552130Smckusick 		extern caddr_t vmUserMap();
70652130Smckusick 
70752130Smckusick 		/*
70852130Smckusick 		 * Map the all the data the user needs access to into
70952130Smckusick 		 * user space.
71052130Smckusick 		 */
71152130Smckusick 		addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
71252130Smckusick 		if (addr == (caddr_t)0)
71352130Smckusick 			goto mapError;
71452130Smckusick 		*(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
71552130Smckusick 		pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
71652130Smckusick 		pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
71752130Smckusick 		/*
71852130Smckusick 		 * Map the plane mask into the user's address space.
71952130Smckusick 		 */
72052130Smckusick 		addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR);
72152130Smckusick 		if (addr == (caddr_t)0)
72252130Smckusick 			goto mapError;
72352130Smckusick 		pmu.scrInfo.planemask = (char *)addr;
72452130Smckusick 		/*
72552862Sralph 		 * Map the frame buffer into the user's address space.
72652130Smckusick 		 */
72752130Smckusick 		addr = vmUserMap(isMono ? 256*1024 : 1024*1024,
72852130Smckusick 			(unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR);
72952130Smckusick 		if (addr == (caddr_t)0)
73052130Smckusick 			goto mapError;
73152130Smckusick 		pmu.scrInfo.bitmap = (char *)addr;
73252130Smckusick 		break;
73352130Smckusick 
73452130Smckusick 	mapError:
73552130Smckusick 		vmUserUnmap();
73652130Smckusick 		printf("Cannot map shared data structures\n");
73752130Smckusick 		return (EIO);
73852130Smckusick 	    }
73952130Smckusick 
74052130Smckusick 	case QIOCPMSTATE:
74152130Smckusick 		/*
74252130Smckusick 		 * Set mouse state.
74352130Smckusick 		 */
74452130Smckusick 		pmu.scrInfo.mouse = *(pmCursor *)data;
74552130Smckusick 		PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
74652130Smckusick 		break;
74752130Smckusick 
74852130Smckusick 	case QIOCINIT:
74952130Smckusick 		/*
75052130Smckusick 		 * Initialize the screen.
75152130Smckusick 		 */
75252130Smckusick 		ScreenInit();
75352130Smckusick 		break;
75452130Smckusick 
75552130Smckusick 	case QIOCKPCMD:
75652130Smckusick 	    {
75752130Smckusick 		pmKpCmd *kpCmdPtr;
75852130Smckusick 		unsigned char *cp;
75952130Smckusick 
76052130Smckusick 		kpCmdPtr = (pmKpCmd *)data;
76152130Smckusick 		if (kpCmdPtr->nbytes == 0)
76252130Smckusick 			kpCmdPtr->cmd |= 0x80;
76352130Smckusick 		if (!GraphicsOpen)
76452130Smckusick 			kpCmdPtr->cmd |= 1;
76552130Smckusick 		dcKBDPutc((int)kpCmdPtr->cmd);
76652130Smckusick 		cp = &kpCmdPtr->par[0];
76752130Smckusick 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
76852130Smckusick 			if (kpCmdPtr->nbytes == 1)
76952130Smckusick 				*cp |= 0x80;
77052130Smckusick 			dcKBDPutc((int)*cp);
77152130Smckusick 		}
77252130Smckusick 		break;
77352130Smckusick 	    }
77452130Smckusick 
77552130Smckusick 	case QIOCADDR:
77652130Smckusick 		*(PM_Info **)data = &pmu.scrInfo;
77752130Smckusick 		break;
77852130Smckusick 
77952130Smckusick 	case QIOWCURSOR:
78052130Smckusick 		LoadCursor((unsigned short *)data);
78152130Smckusick 		break;
78252130Smckusick 
78352130Smckusick 	case QIOWCURSORCOLOR:
78452130Smckusick 		CursorColor((unsigned int *)data);
78552130Smckusick 		break;
78652130Smckusick 
78752130Smckusick 	case QIOSETCMAP:
78852130Smckusick 		LoadColorMap((ColorMap *)data);
78952130Smckusick 		break;
79052130Smckusick 
79152130Smckusick 	case QIOKERNLOOP:
79252960Sralph 		s = spltty();
79352862Sralph 		dcDivertXInput = pmKbdEvent;
79452862Sralph 		dcMouseEvent = pmMouseEvent;
79552862Sralph 		dcMouseButtons = pmMouseButtons;
79652960Sralph 		splx(s);
79752130Smckusick 		break;
79852130Smckusick 
79952130Smckusick 	case QIOKERNUNLOOP:
80052960Sralph 		s = spltty();
80152862Sralph 		dcDivertXInput = (void (*)())0;
80252862Sralph 		dcMouseEvent = (void (*)())0;
80352862Sralph 		dcMouseButtons = (void (*)())0;
80452960Sralph 		splx(s);
80552130Smckusick 		break;
80652130Smckusick 
80752130Smckusick 	case QIOVIDEOON:
80852130Smckusick 		if (!isMono)
80952130Smckusick 			RestoreCursorColor();
81052130Smckusick 		curReg |= PCC_ENPA;
81152130Smckusick 		curReg &= ~PCC_FOPB;
81252130Smckusick 		pcc->cmdr = curReg;
81352130Smckusick 		break;
81452130Smckusick 
81552130Smckusick 	case QIOVIDEOOFF:
81652130Smckusick 		if (!isMono)
81752130Smckusick 			VDACInit();
81852130Smckusick 		curReg |= PCC_FOPB;
81952130Smckusick 		curReg &= ~PCC_ENPA;
82052130Smckusick 		pcc->cmdr = curReg;
82152130Smckusick 		break;
82252130Smckusick 
82352130Smckusick 	default:
82452862Sralph 		printf("pm0: Unknown ioctl command %x\n", cmd);
82552130Smckusick 		return (EINVAL);
82652130Smckusick 	}
82752130Smckusick 	return (0);
82852130Smckusick }
82952130Smckusick 
83052675Smckusick pmselect(dev, flag, p)
83152130Smckusick 	dev_t dev;
83252130Smckusick 	int flag;
83352675Smckusick 	struct proc *p;
83452130Smckusick {
83552130Smckusick 
83652130Smckusick 	switch (flag) {
83752130Smckusick 	case FREAD:
83852130Smckusick 		if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
83952130Smckusick 			return (1);
84052675Smckusick 		selrecord(p, &pm_selp);
84152130Smckusick 		break;
84252130Smckusick 	}
84352130Smckusick 
84452130Smckusick 	return (0);
84552130Smckusick }
84652862Sralph 
84752862Sralph static u_char	bg_RGB[3];	/* background color for the cursor */
84852862Sralph static u_char	fg_RGB[3];	/* foreground color for the cursor */
84952862Sralph 
85052862Sralph /*
85152862Sralph  * The default cursor.
85252862Sralph  */
85352862Sralph unsigned short defCursor[32] = {
85452862Sralph /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85552862Sralph 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85652862Sralph /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85752862Sralph               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
85852862Sralph 
85952862Sralph };
86052862Sralph 
86152862Sralph /*
86252862Sralph  * Test to see if device is present.
86352862Sralph  * Return true if found and initialized ok.
86452862Sralph  */
86552862Sralph pminit()
86652862Sralph {
86752862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
86852862Sralph 
86952862Sralph 	isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO;
87052862Sralph 	if (isMono) {
87152862Sralph 		/* check for no frame buffer */
87252862Sralph 		if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4))
87352862Sralph 			return (0);
87452862Sralph 	}
87552862Sralph 
87652862Sralph 	/*
87752862Sralph 	 * Initialize the screen.
87852862Sralph 	 */
87952862Sralph 	pcc->cmdr = PCC_FOPB | PCC_VBHI;
88052862Sralph 
88152862Sralph 	/*
88252862Sralph 	 * Initialize the cursor register.
88352862Sralph 	 */
88452862Sralph 	pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB;
88552862Sralph 
88652862Sralph 	/*
88752862Sralph 	 * Initialize screen info.
88852862Sralph 	 */
88952862Sralph 	pmu.scrInfo.max_row = 56;
89052862Sralph 	pmu.scrInfo.max_col = 80;
89152862Sralph 	pmu.scrInfo.max_x = 1024;
89252862Sralph 	pmu.scrInfo.max_y = 864;
89352862Sralph 	pmu.scrInfo.max_cur_x = 1023;
89452862Sralph 	pmu.scrInfo.max_cur_y = 863;
89552862Sralph 	pmu.scrInfo.version = 11;
89652862Sralph 	pmu.scrInfo.mthreshold = 4;
89752862Sralph 	pmu.scrInfo.mscale = 2;
89852862Sralph 	pmu.scrInfo.min_cur_x = -15;
89952862Sralph 	pmu.scrInfo.min_cur_y = -15;
90052862Sralph 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
90152862Sralph 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
90252862Sralph 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
90352862Sralph 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
90452862Sralph 	pmu.scrInfo.qe.tcNext = 0;
90552862Sralph 
90652862Sralph 	/*
90752862Sralph 	 * Initialize the color map, the screen, and the mouse.
90852862Sralph 	 */
90952862Sralph 	InitColorMap();
91052862Sralph 	ScreenInit();
91152862Sralph 	Scroll();
91252862Sralph 
91352862Sralph 	initialized = 1;
91452862Sralph 	return (1);
91552862Sralph }
91652862Sralph 
91752862Sralph /*
91852862Sralph  * ----------------------------------------------------------------------------
91952862Sralph  *
92052862Sralph  * ScreenInit --
92152862Sralph  *
92252862Sralph  *	Initialize the screen.
92352862Sralph  *
92452862Sralph  * Results:
92552862Sralph  *	None.
92652862Sralph  *
92752862Sralph  * Side effects:
92852862Sralph  *	The screen is initialized.
92952862Sralph  *
93052862Sralph  * ----------------------------------------------------------------------------
93152862Sralph  */
93252862Sralph static void
93352862Sralph ScreenInit()
93452862Sralph {
93552862Sralph 
93652862Sralph 	/*
93752862Sralph 	 * Home the cursor.
93852862Sralph 	 * We want an LSI terminal emulation.  We want the graphics
93952862Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
94052862Sralph 	 */
94152862Sralph 	row = 55;
94252862Sralph 	col = 0;
94352862Sralph 
94452862Sralph 	/*
94552862Sralph 	 * Load the cursor with the default values
94652862Sralph 	 *
94752862Sralph 	 */
94852862Sralph 	LoadCursor(defCursor);
94952862Sralph }
95052862Sralph 
95152862Sralph /*
95252862Sralph  * ----------------------------------------------------------------------------
95352862Sralph  *
95452862Sralph  * LoadCursor --
95552862Sralph  *
95652862Sralph  *	Routine to load the cursor Sprite pattern.
95752862Sralph  *
95852862Sralph  * Results:
95952862Sralph  *	None.
96052862Sralph  *
96152862Sralph  * Side effects:
96252862Sralph  *	The cursor is loaded into the hardware cursor.
96352862Sralph  *
96452862Sralph  * ----------------------------------------------------------------------------
96552862Sralph  */
96652862Sralph static void
96752862Sralph LoadCursor(cur)
96852862Sralph 	unsigned short *cur;
96952862Sralph {
97052862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
97152862Sralph 	register int i;
97252862Sralph 
97352862Sralph 	curReg |= PCC_LODSA;
97452862Sralph 	pcc->cmdr = curReg;
97552862Sralph 	for (i = 0; i < 32; i++) {
97652862Sralph 		pcc->memory = cur[i];
97752862Sralph 		MachEmptyWriteBuffer();
97852862Sralph 	}
97952862Sralph 	curReg &= ~PCC_LODSA;
98052862Sralph 	pcc->cmdr = curReg;
98152862Sralph }
98252862Sralph 
98352862Sralph /*
98452862Sralph  * ----------------------------------------------------------------------------
98552862Sralph  *
98652862Sralph  * RestoreCursorColor --
98752862Sralph  *
98852862Sralph  *	Routine to restore the color of the cursor.
98952862Sralph  *
99052862Sralph  * Results:
99152862Sralph  *	None.
99252862Sralph  *
99352862Sralph  * Side effects:
99452862Sralph  *	None.
99552862Sralph  *
99652862Sralph  * ----------------------------------------------------------------------------
99752862Sralph  */
99852862Sralph static void
99952862Sralph RestoreCursorColor()
100052862Sralph {
100152862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
100252862Sralph 	register int i;
100352862Sralph 
100452862Sralph 	vdac->overWA = 0x04;
100552862Sralph 	MachEmptyWriteBuffer();
100652862Sralph 	for (i = 0; i < 3; i++) {
100752862Sralph 		vdac->over = bg_RGB[i];
100852862Sralph 		MachEmptyWriteBuffer();
100952862Sralph 	}
101052862Sralph 
101152862Sralph 	vdac->overWA = 0x08;
101252862Sralph 	MachEmptyWriteBuffer();
101352862Sralph 	vdac->over = 0x00;
101452862Sralph 	MachEmptyWriteBuffer();
101552862Sralph 	vdac->over = 0x00;
101652862Sralph 	MachEmptyWriteBuffer();
101752862Sralph 	vdac->over = 0x7f;
101852862Sralph 	MachEmptyWriteBuffer();
101952862Sralph 
102052862Sralph 	vdac->overWA = 0x0c;
102152862Sralph 	MachEmptyWriteBuffer();
102252862Sralph 	for (i = 0; i < 3; i++) {
102352862Sralph 		vdac->over = fg_RGB[i];
102452862Sralph 		MachEmptyWriteBuffer();
102552862Sralph 	}
102652862Sralph }
102752862Sralph 
102852862Sralph /*
102952862Sralph  * ----------------------------------------------------------------------------
103052862Sralph  *
103152862Sralph  * CursorColor --
103252862Sralph  *
103352862Sralph  *	Set the color of the cursor.
103452862Sralph  *
103552862Sralph  * Results:
103652862Sralph  *	None.
103752862Sralph  *
103852862Sralph  * Side effects:
103952862Sralph  *	None.
104052862Sralph  *
104152862Sralph  * ----------------------------------------------------------------------------
104252862Sralph  */
104352862Sralph static void
104452862Sralph CursorColor(color)
104552862Sralph 	unsigned int color[];
104652862Sralph {
104752862Sralph 	register int i, j;
104852862Sralph 
104952862Sralph 	for (i = 0; i < 3; i++)
105052862Sralph 		bg_RGB[i] = (u_char)(color[i] >> 8);
105152862Sralph 
105252862Sralph 	for (i = 3, j = 0; i < 6; i++, j++)
105352862Sralph 		fg_RGB[j] = (u_char)(color[i] >> 8);
105452862Sralph 
105552862Sralph 	RestoreCursorColor();
105652862Sralph }
105752862Sralph 
105852862Sralph /*
105952862Sralph  * ----------------------------------------------------------------------------
106052862Sralph  *
106152862Sralph  * InitColorMap --
106252862Sralph  *
106352862Sralph  *	Initialize the color map.
106452862Sralph  *
106552862Sralph  * Results:
106652862Sralph  *	None.
106752862Sralph  *
106852862Sralph  * Side effects:
106952862Sralph  *	The colormap is initialized appropriately whether it is color or
107052862Sralph  *	monochrome.
107152862Sralph  *
107252862Sralph  * ----------------------------------------------------------------------------
107352862Sralph  */
107452862Sralph static void
107552862Sralph InitColorMap()
107652862Sralph {
107752862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
107852862Sralph 	register int i;
107952862Sralph 
108052862Sralph 	*(char *)MACH_PLANE_MASK_ADDR = 0xff;
108152862Sralph 	MachEmptyWriteBuffer();
108252862Sralph 
108352862Sralph 	if (isMono) {
108452862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
108552862Sralph 		for (i = 0; i < 256; i++) {
108652862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
108752862Sralph 			MachEmptyWriteBuffer();
108852862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
108952862Sralph 			MachEmptyWriteBuffer();
109052862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
109152862Sralph 			MachEmptyWriteBuffer();
109252862Sralph 		}
109352862Sralph 	} else {
109452862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
109552862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109652862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109752862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109852862Sralph 
109952862Sralph 		for (i = 1; i < 256; i++) {
110052862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110152862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110252862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110352862Sralph 		}
110452862Sralph 	}
110552862Sralph 
110652862Sralph 	for (i = 0; i < 3; i++) {
110752862Sralph 		bg_RGB[i] = 0x00;
110852862Sralph 		fg_RGB[i] = 0xff;
110952862Sralph 	}
111052862Sralph 	RestoreCursorColor();
111152862Sralph }
111252862Sralph 
111352862Sralph /*
111452862Sralph  * ----------------------------------------------------------------------------
111552862Sralph  *
111652862Sralph  * VDACInit --
111752862Sralph  *
111852862Sralph  *	Initialize the VDAC.
111952862Sralph  *
112052862Sralph  * Results:
112152862Sralph  *	None.
112252862Sralph  *
112352862Sralph  * Side effects:
112452862Sralph  *	None.
112552862Sralph  *
112652862Sralph  * ----------------------------------------------------------------------------
112752862Sralph  */
112852862Sralph static void
112952862Sralph VDACInit()
113052862Sralph {
113152862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
113252862Sralph 
113352862Sralph 	/*
113452862Sralph 	 *
113552862Sralph 	 * Initialize the VDAC
113652862Sralph 	 */
113752862Sralph 	vdac->overWA = 0x04; MachEmptyWriteBuffer();
113852862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
113952862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114052862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114152862Sralph 	vdac->overWA = 0x08; MachEmptyWriteBuffer();
114252862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114352862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114452862Sralph 	vdac->over = 0x7f; MachEmptyWriteBuffer();
114552862Sralph 	vdac->overWA = 0x0c; MachEmptyWriteBuffer();
114652862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114752862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114852862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114952862Sralph }
115052862Sralph 
115152862Sralph /*
115252862Sralph  * ----------------------------------------------------------------------------
115352862Sralph  *
115452862Sralph  * LoadColorMap --
115552862Sralph  *
115652862Sralph  *	Load the color map.
115752862Sralph  *
115852862Sralph  * Results:
115952862Sralph  *	None.
116052862Sralph  *
116152862Sralph  * Side effects:
116252862Sralph  *	The color map is loaded.
116352862Sralph  *
116452862Sralph  * ----------------------------------------------------------------------------
116552862Sralph  */
116652862Sralph static void
116752862Sralph LoadColorMap(ptr)
116852862Sralph 	ColorMap *ptr;
116952862Sralph {
117052862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
117152862Sralph 
117252862Sralph 	if (ptr->index > 256)
117352862Sralph 		return;
117452862Sralph 
117552862Sralph 	vdac->mapWA = ptr->index; MachEmptyWriteBuffer();
117652862Sralph 	vdac->map = ptr->Entry.red; MachEmptyWriteBuffer();
117752862Sralph 	vdac->map = ptr->Entry.green; MachEmptyWriteBuffer();
117852862Sralph 	vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer();
117952862Sralph }
118052862Sralph 
118152862Sralph /*
118252862Sralph  *----------------------------------------------------------------------
118352862Sralph  *
118452862Sralph  * PosCursor --
118552862Sralph  *
118652862Sralph  *	Postion the cursor.
118752862Sralph  *
118852862Sralph  * Results:
118952862Sralph  *	None.
119052862Sralph  *
119152862Sralph  * Side effects:
119252862Sralph  *	None.
119352862Sralph  *
119452862Sralph  *----------------------------------------------------------------------
119552862Sralph  */
119652862Sralph static void
119752862Sralph PosCursor(x, y)
119852862Sralph 	register int x, y;
119952862Sralph {
120052862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
120152862Sralph 
120252862Sralph 	if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
120352862Sralph 		y = pmu.scrInfo.max_cur_y;
120452862Sralph 	if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
120552862Sralph 		x = pmu.scrInfo.max_cur_x;
120652862Sralph 	pmu.scrInfo.cursor.x = x;		/* keep track of real cursor */
120752862Sralph 	pmu.scrInfo.cursor.y = y;		/* position, indep. of mouse */
120852862Sralph 	pcc->xpos = PCC_X_OFFSET + x;
120952862Sralph 	pcc->ypos = PCC_Y_OFFSET + y;
121052862Sralph }
121152130Smckusick #endif
1212