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