xref: /csrg-svn/sys/pmax/dev/pm.c (revision 53823)
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*53823Smckusick  *	@(#)pm.c	7.5 (Berkeley) 06/02/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 {
640*53823Smckusick 	int s;
64152130Smckusick 
64252130Smckusick 	if (!initialized)
64352130Smckusick 		return (ENXIO);
64452130Smckusick 	if (GraphicsOpen)
64552130Smckusick 		return (EBUSY);
64652130Smckusick 
64752130Smckusick 	GraphicsOpen = 1;
64852130Smckusick 	if (!isMono)
64952130Smckusick 		InitColorMap();
65052130Smckusick 	/*
65152130Smckusick 	 * Set up event queue for later
65252130Smckusick 	 */
65352130Smckusick 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
65452130Smckusick 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
65552130Smckusick 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
65652130Smckusick 	pmu.scrInfo.qe.tcNext = 0;
65752130Smckusick 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
658*53823Smckusick 	s = spltty();
659*53823Smckusick 	dcDivertXInput = pmKbdEvent;
660*53823Smckusick 	dcMouseEvent = pmMouseEvent;
661*53823Smckusick 	dcMouseButtons = pmMouseButtons;
662*53823Smckusick 	splx(s);
66352130Smckusick 	return (0);
66452130Smckusick }
66552130Smckusick 
66652130Smckusick /*ARGSUSED*/
66752130Smckusick pmclose(dev, flag)
66852130Smckusick 	dev_t dev;
66952130Smckusick 	int flag;
67052130Smckusick {
67152960Sralph 	int s;
67252130Smckusick 
67352130Smckusick 	if (!GraphicsOpen)
67452130Smckusick 		return (EBADF);
67552130Smckusick 
67652130Smckusick 	GraphicsOpen = 0;
67752130Smckusick 	if (!isMono)
67852130Smckusick 		InitColorMap();
67952960Sralph 	s = spltty();
68052960Sralph 	dcDivertXInput = (void (*)())0;
68152960Sralph 	dcMouseEvent = (void (*)())0;
68252960Sralph 	dcMouseButtons = (void (*)())0;
68352960Sralph 	splx(s);
68452130Smckusick 	ScreenInit();
68552130Smckusick 	vmUserUnmap();
68652862Sralph 	bzero((caddr_t)MACH_UNCACHED_FRAME_BUFFER_ADDR,
68752862Sralph 		(isMono ? 1024 / 8 : 1024) * 864);
68852862Sralph 	PosCursor(col * 8, row * 15);
68952130Smckusick 	return (0);
69052130Smckusick }
69152130Smckusick 
69252130Smckusick /*ARGSUSED*/
69352130Smckusick pmioctl(dev, cmd, data, flag)
69452130Smckusick 	dev_t dev;
69552130Smckusick 	caddr_t data;
69652130Smckusick {
69752130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
69852960Sralph 	int s;
69952130Smckusick 
70052130Smckusick 	switch (cmd) {
70152130Smckusick 	case QIOCGINFO:
70252130Smckusick 	    {
70352130Smckusick 		caddr_t addr;
70452130Smckusick 		extern caddr_t vmUserMap();
70552130Smckusick 
70652130Smckusick 		/*
70752130Smckusick 		 * Map the all the data the user needs access to into
70852130Smckusick 		 * user space.
70952130Smckusick 		 */
71052130Smckusick 		addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
71152130Smckusick 		if (addr == (caddr_t)0)
71252130Smckusick 			goto mapError;
71352130Smckusick 		*(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
71452130Smckusick 		pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
71552130Smckusick 		pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
71652130Smckusick 		/*
71752130Smckusick 		 * Map the plane mask into the user's address space.
71852130Smckusick 		 */
71952130Smckusick 		addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR);
72052130Smckusick 		if (addr == (caddr_t)0)
72152130Smckusick 			goto mapError;
72252130Smckusick 		pmu.scrInfo.planemask = (char *)addr;
72352130Smckusick 		/*
72452862Sralph 		 * Map the frame buffer into the user's address space.
72552130Smckusick 		 */
72652130Smckusick 		addr = vmUserMap(isMono ? 256*1024 : 1024*1024,
72752130Smckusick 			(unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR);
72852130Smckusick 		if (addr == (caddr_t)0)
72952130Smckusick 			goto mapError;
73052130Smckusick 		pmu.scrInfo.bitmap = (char *)addr;
73152130Smckusick 		break;
73252130Smckusick 
73352130Smckusick 	mapError:
73452130Smckusick 		vmUserUnmap();
73552130Smckusick 		printf("Cannot map shared data structures\n");
73652130Smckusick 		return (EIO);
73752130Smckusick 	    }
73852130Smckusick 
73952130Smckusick 	case QIOCPMSTATE:
74052130Smckusick 		/*
74152130Smckusick 		 * Set mouse state.
74252130Smckusick 		 */
74352130Smckusick 		pmu.scrInfo.mouse = *(pmCursor *)data;
74452130Smckusick 		PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
74552130Smckusick 		break;
74652130Smckusick 
74752130Smckusick 	case QIOCINIT:
74852130Smckusick 		/*
74952130Smckusick 		 * Initialize the screen.
75052130Smckusick 		 */
75152130Smckusick 		ScreenInit();
75252130Smckusick 		break;
75352130Smckusick 
75452130Smckusick 	case QIOCKPCMD:
75552130Smckusick 	    {
75652130Smckusick 		pmKpCmd *kpCmdPtr;
75752130Smckusick 		unsigned char *cp;
75852130Smckusick 
75952130Smckusick 		kpCmdPtr = (pmKpCmd *)data;
76052130Smckusick 		if (kpCmdPtr->nbytes == 0)
76152130Smckusick 			kpCmdPtr->cmd |= 0x80;
76252130Smckusick 		if (!GraphicsOpen)
76352130Smckusick 			kpCmdPtr->cmd |= 1;
76452130Smckusick 		dcKBDPutc((int)kpCmdPtr->cmd);
76552130Smckusick 		cp = &kpCmdPtr->par[0];
76652130Smckusick 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
76752130Smckusick 			if (kpCmdPtr->nbytes == 1)
76852130Smckusick 				*cp |= 0x80;
76952130Smckusick 			dcKBDPutc((int)*cp);
77052130Smckusick 		}
77152130Smckusick 		break;
77252130Smckusick 	    }
77352130Smckusick 
77452130Smckusick 	case QIOCADDR:
77552130Smckusick 		*(PM_Info **)data = &pmu.scrInfo;
77652130Smckusick 		break;
77752130Smckusick 
77852130Smckusick 	case QIOWCURSOR:
77952130Smckusick 		LoadCursor((unsigned short *)data);
78052130Smckusick 		break;
78152130Smckusick 
78252130Smckusick 	case QIOWCURSORCOLOR:
78352130Smckusick 		CursorColor((unsigned int *)data);
78452130Smckusick 		break;
78552130Smckusick 
78652130Smckusick 	case QIOSETCMAP:
78752130Smckusick 		LoadColorMap((ColorMap *)data);
78852130Smckusick 		break;
78952130Smckusick 
79052130Smckusick 	case QIOKERNLOOP:
79152960Sralph 		s = spltty();
79252862Sralph 		dcDivertXInput = pmKbdEvent;
79352862Sralph 		dcMouseEvent = pmMouseEvent;
79452862Sralph 		dcMouseButtons = pmMouseButtons;
79552960Sralph 		splx(s);
79652130Smckusick 		break;
79752130Smckusick 
79852130Smckusick 	case QIOKERNUNLOOP:
79952960Sralph 		s = spltty();
80052862Sralph 		dcDivertXInput = (void (*)())0;
80152862Sralph 		dcMouseEvent = (void (*)())0;
80252862Sralph 		dcMouseButtons = (void (*)())0;
80352960Sralph 		splx(s);
80452130Smckusick 		break;
80552130Smckusick 
80652130Smckusick 	case QIOVIDEOON:
80752130Smckusick 		if (!isMono)
80852130Smckusick 			RestoreCursorColor();
80952130Smckusick 		curReg |= PCC_ENPA;
81052130Smckusick 		curReg &= ~PCC_FOPB;
81152130Smckusick 		pcc->cmdr = curReg;
81252130Smckusick 		break;
81352130Smckusick 
81452130Smckusick 	case QIOVIDEOOFF:
81552130Smckusick 		if (!isMono)
81652130Smckusick 			VDACInit();
81752130Smckusick 		curReg |= PCC_FOPB;
81852130Smckusick 		curReg &= ~PCC_ENPA;
81952130Smckusick 		pcc->cmdr = curReg;
82052130Smckusick 		break;
82152130Smckusick 
82252130Smckusick 	default:
82352862Sralph 		printf("pm0: Unknown ioctl command %x\n", cmd);
82452130Smckusick 		return (EINVAL);
82552130Smckusick 	}
82652130Smckusick 	return (0);
82752130Smckusick }
82852130Smckusick 
82952675Smckusick pmselect(dev, flag, p)
83052130Smckusick 	dev_t dev;
83152130Smckusick 	int flag;
83252675Smckusick 	struct proc *p;
83352130Smckusick {
83452130Smckusick 
83552130Smckusick 	switch (flag) {
83652130Smckusick 	case FREAD:
83752130Smckusick 		if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
83852130Smckusick 			return (1);
83952675Smckusick 		selrecord(p, &pm_selp);
84052130Smckusick 		break;
84152130Smckusick 	}
84252130Smckusick 
84352130Smckusick 	return (0);
84452130Smckusick }
84552862Sralph 
84652862Sralph static u_char	bg_RGB[3];	/* background color for the cursor */
84752862Sralph static u_char	fg_RGB[3];	/* foreground color for the cursor */
84852862Sralph 
84952862Sralph /*
85052862Sralph  * The default cursor.
85152862Sralph  */
85252862Sralph unsigned short defCursor[32] = {
85352862Sralph /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85452862Sralph 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85552862Sralph /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
85652862Sralph               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
85752862Sralph 
85852862Sralph };
85952862Sralph 
86052862Sralph /*
86152862Sralph  * Test to see if device is present.
86252862Sralph  * Return true if found and initialized ok.
86352862Sralph  */
86452862Sralph pminit()
86552862Sralph {
86652862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
86752862Sralph 
86852862Sralph 	isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO;
86952862Sralph 	if (isMono) {
87052862Sralph 		/* check for no frame buffer */
87152862Sralph 		if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4))
87252862Sralph 			return (0);
87352862Sralph 	}
87452862Sralph 
87552862Sralph 	/*
87652862Sralph 	 * Initialize the screen.
87752862Sralph 	 */
87852862Sralph 	pcc->cmdr = PCC_FOPB | PCC_VBHI;
87952862Sralph 
88052862Sralph 	/*
88152862Sralph 	 * Initialize the cursor register.
88252862Sralph 	 */
88352862Sralph 	pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB;
88452862Sralph 
88552862Sralph 	/*
88652862Sralph 	 * Initialize screen info.
88752862Sralph 	 */
88852862Sralph 	pmu.scrInfo.max_row = 56;
88952862Sralph 	pmu.scrInfo.max_col = 80;
89052862Sralph 	pmu.scrInfo.max_x = 1024;
89152862Sralph 	pmu.scrInfo.max_y = 864;
89252862Sralph 	pmu.scrInfo.max_cur_x = 1023;
89352862Sralph 	pmu.scrInfo.max_cur_y = 863;
89452862Sralph 	pmu.scrInfo.version = 11;
89552862Sralph 	pmu.scrInfo.mthreshold = 4;
89652862Sralph 	pmu.scrInfo.mscale = 2;
89752862Sralph 	pmu.scrInfo.min_cur_x = -15;
89852862Sralph 	pmu.scrInfo.min_cur_y = -15;
89952862Sralph 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
90052862Sralph 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
90152862Sralph 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
90252862Sralph 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
90352862Sralph 	pmu.scrInfo.qe.tcNext = 0;
90452862Sralph 
90552862Sralph 	/*
90652862Sralph 	 * Initialize the color map, the screen, and the mouse.
90752862Sralph 	 */
90852862Sralph 	InitColorMap();
90952862Sralph 	ScreenInit();
91052862Sralph 	Scroll();
91152862Sralph 
91252862Sralph 	initialized = 1;
91352862Sralph 	return (1);
91452862Sralph }
91552862Sralph 
91652862Sralph /*
91752862Sralph  * ----------------------------------------------------------------------------
91852862Sralph  *
91952862Sralph  * ScreenInit --
92052862Sralph  *
92152862Sralph  *	Initialize the screen.
92252862Sralph  *
92352862Sralph  * Results:
92452862Sralph  *	None.
92552862Sralph  *
92652862Sralph  * Side effects:
92752862Sralph  *	The screen is initialized.
92852862Sralph  *
92952862Sralph  * ----------------------------------------------------------------------------
93052862Sralph  */
93152862Sralph static void
93252862Sralph ScreenInit()
93352862Sralph {
93452862Sralph 
93552862Sralph 	/*
93652862Sralph 	 * Home the cursor.
93752862Sralph 	 * We want an LSI terminal emulation.  We want the graphics
93852862Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
93952862Sralph 	 */
94052862Sralph 	row = 55;
94152862Sralph 	col = 0;
94252862Sralph 
94352862Sralph 	/*
94452862Sralph 	 * Load the cursor with the default values
94552862Sralph 	 *
94652862Sralph 	 */
94752862Sralph 	LoadCursor(defCursor);
94852862Sralph }
94952862Sralph 
95052862Sralph /*
95152862Sralph  * ----------------------------------------------------------------------------
95252862Sralph  *
95352862Sralph  * LoadCursor --
95452862Sralph  *
95552862Sralph  *	Routine to load the cursor Sprite pattern.
95652862Sralph  *
95752862Sralph  * Results:
95852862Sralph  *	None.
95952862Sralph  *
96052862Sralph  * Side effects:
96152862Sralph  *	The cursor is loaded into the hardware cursor.
96252862Sralph  *
96352862Sralph  * ----------------------------------------------------------------------------
96452862Sralph  */
96552862Sralph static void
96652862Sralph LoadCursor(cur)
96752862Sralph 	unsigned short *cur;
96852862Sralph {
96952862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
97052862Sralph 	register int i;
97152862Sralph 
97252862Sralph 	curReg |= PCC_LODSA;
97352862Sralph 	pcc->cmdr = curReg;
97452862Sralph 	for (i = 0; i < 32; i++) {
97552862Sralph 		pcc->memory = cur[i];
97652862Sralph 		MachEmptyWriteBuffer();
97752862Sralph 	}
97852862Sralph 	curReg &= ~PCC_LODSA;
97952862Sralph 	pcc->cmdr = curReg;
98052862Sralph }
98152862Sralph 
98252862Sralph /*
98352862Sralph  * ----------------------------------------------------------------------------
98452862Sralph  *
98552862Sralph  * RestoreCursorColor --
98652862Sralph  *
98752862Sralph  *	Routine to restore the color of the cursor.
98852862Sralph  *
98952862Sralph  * Results:
99052862Sralph  *	None.
99152862Sralph  *
99252862Sralph  * Side effects:
99352862Sralph  *	None.
99452862Sralph  *
99552862Sralph  * ----------------------------------------------------------------------------
99652862Sralph  */
99752862Sralph static void
99852862Sralph RestoreCursorColor()
99952862Sralph {
100052862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
100152862Sralph 	register int i;
100252862Sralph 
100352862Sralph 	vdac->overWA = 0x04;
100452862Sralph 	MachEmptyWriteBuffer();
100552862Sralph 	for (i = 0; i < 3; i++) {
100652862Sralph 		vdac->over = bg_RGB[i];
100752862Sralph 		MachEmptyWriteBuffer();
100852862Sralph 	}
100952862Sralph 
101052862Sralph 	vdac->overWA = 0x08;
101152862Sralph 	MachEmptyWriteBuffer();
101252862Sralph 	vdac->over = 0x00;
101352862Sralph 	MachEmptyWriteBuffer();
101452862Sralph 	vdac->over = 0x00;
101552862Sralph 	MachEmptyWriteBuffer();
101652862Sralph 	vdac->over = 0x7f;
101752862Sralph 	MachEmptyWriteBuffer();
101852862Sralph 
101952862Sralph 	vdac->overWA = 0x0c;
102052862Sralph 	MachEmptyWriteBuffer();
102152862Sralph 	for (i = 0; i < 3; i++) {
102252862Sralph 		vdac->over = fg_RGB[i];
102352862Sralph 		MachEmptyWriteBuffer();
102452862Sralph 	}
102552862Sralph }
102652862Sralph 
102752862Sralph /*
102852862Sralph  * ----------------------------------------------------------------------------
102952862Sralph  *
103052862Sralph  * CursorColor --
103152862Sralph  *
103252862Sralph  *	Set the color of the cursor.
103352862Sralph  *
103452862Sralph  * Results:
103552862Sralph  *	None.
103652862Sralph  *
103752862Sralph  * Side effects:
103852862Sralph  *	None.
103952862Sralph  *
104052862Sralph  * ----------------------------------------------------------------------------
104152862Sralph  */
104252862Sralph static void
104352862Sralph CursorColor(color)
104452862Sralph 	unsigned int color[];
104552862Sralph {
104652862Sralph 	register int i, j;
104752862Sralph 
104852862Sralph 	for (i = 0; i < 3; i++)
104952862Sralph 		bg_RGB[i] = (u_char)(color[i] >> 8);
105052862Sralph 
105152862Sralph 	for (i = 3, j = 0; i < 6; i++, j++)
105252862Sralph 		fg_RGB[j] = (u_char)(color[i] >> 8);
105352862Sralph 
105452862Sralph 	RestoreCursorColor();
105552862Sralph }
105652862Sralph 
105752862Sralph /*
105852862Sralph  * ----------------------------------------------------------------------------
105952862Sralph  *
106052862Sralph  * InitColorMap --
106152862Sralph  *
106252862Sralph  *	Initialize the color map.
106352862Sralph  *
106452862Sralph  * Results:
106552862Sralph  *	None.
106652862Sralph  *
106752862Sralph  * Side effects:
106852862Sralph  *	The colormap is initialized appropriately whether it is color or
106952862Sralph  *	monochrome.
107052862Sralph  *
107152862Sralph  * ----------------------------------------------------------------------------
107252862Sralph  */
107352862Sralph static void
107452862Sralph InitColorMap()
107552862Sralph {
107652862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
107752862Sralph 	register int i;
107852862Sralph 
107952862Sralph 	*(char *)MACH_PLANE_MASK_ADDR = 0xff;
108052862Sralph 	MachEmptyWriteBuffer();
108152862Sralph 
108252862Sralph 	if (isMono) {
108352862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
108452862Sralph 		for (i = 0; i < 256; i++) {
108552862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
108652862Sralph 			MachEmptyWriteBuffer();
108752862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
108852862Sralph 			MachEmptyWriteBuffer();
108952862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
109052862Sralph 			MachEmptyWriteBuffer();
109152862Sralph 		}
109252862Sralph 	} else {
109352862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
109452862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109552862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109652862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
109752862Sralph 
109852862Sralph 		for (i = 1; i < 256; i++) {
109952862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110052862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110152862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
110252862Sralph 		}
110352862Sralph 	}
110452862Sralph 
110552862Sralph 	for (i = 0; i < 3; i++) {
110652862Sralph 		bg_RGB[i] = 0x00;
110752862Sralph 		fg_RGB[i] = 0xff;
110852862Sralph 	}
110952862Sralph 	RestoreCursorColor();
111052862Sralph }
111152862Sralph 
111252862Sralph /*
111352862Sralph  * ----------------------------------------------------------------------------
111452862Sralph  *
111552862Sralph  * VDACInit --
111652862Sralph  *
111752862Sralph  *	Initialize the VDAC.
111852862Sralph  *
111952862Sralph  * Results:
112052862Sralph  *	None.
112152862Sralph  *
112252862Sralph  * Side effects:
112352862Sralph  *	None.
112452862Sralph  *
112552862Sralph  * ----------------------------------------------------------------------------
112652862Sralph  */
112752862Sralph static void
112852862Sralph VDACInit()
112952862Sralph {
113052862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
113152862Sralph 
113252862Sralph 	/*
113352862Sralph 	 *
113452862Sralph 	 * Initialize the VDAC
113552862Sralph 	 */
113652862Sralph 	vdac->overWA = 0x04; MachEmptyWriteBuffer();
113752862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
113852862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
113952862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114052862Sralph 	vdac->overWA = 0x08; MachEmptyWriteBuffer();
114152862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114252862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
114352862Sralph 	vdac->over = 0x7f; MachEmptyWriteBuffer();
114452862Sralph 	vdac->overWA = 0x0c; MachEmptyWriteBuffer();
114552862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114652862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114752862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
114852862Sralph }
114952862Sralph 
115052862Sralph /*
115152862Sralph  * ----------------------------------------------------------------------------
115252862Sralph  *
115352862Sralph  * LoadColorMap --
115452862Sralph  *
115552862Sralph  *	Load the color map.
115652862Sralph  *
115752862Sralph  * Results:
115852862Sralph  *	None.
115952862Sralph  *
116052862Sralph  * Side effects:
116152862Sralph  *	The color map is loaded.
116252862Sralph  *
116352862Sralph  * ----------------------------------------------------------------------------
116452862Sralph  */
116552862Sralph static void
116652862Sralph LoadColorMap(ptr)
116752862Sralph 	ColorMap *ptr;
116852862Sralph {
116952862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
117052862Sralph 
117152862Sralph 	if (ptr->index > 256)
117252862Sralph 		return;
117352862Sralph 
117452862Sralph 	vdac->mapWA = ptr->index; MachEmptyWriteBuffer();
117552862Sralph 	vdac->map = ptr->Entry.red; MachEmptyWriteBuffer();
117652862Sralph 	vdac->map = ptr->Entry.green; MachEmptyWriteBuffer();
117752862Sralph 	vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer();
117852862Sralph }
117952862Sralph 
118052862Sralph /*
118152862Sralph  *----------------------------------------------------------------------
118252862Sralph  *
118352862Sralph  * PosCursor --
118452862Sralph  *
118552862Sralph  *	Postion the cursor.
118652862Sralph  *
118752862Sralph  * Results:
118852862Sralph  *	None.
118952862Sralph  *
119052862Sralph  * Side effects:
119152862Sralph  *	None.
119252862Sralph  *
119352862Sralph  *----------------------------------------------------------------------
119452862Sralph  */
119552862Sralph static void
119652862Sralph PosCursor(x, y)
119752862Sralph 	register int x, y;
119852862Sralph {
119952862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
120052862Sralph 
120152862Sralph 	if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
120252862Sralph 		y = pmu.scrInfo.max_cur_y;
120352862Sralph 	if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
120452862Sralph 		x = pmu.scrInfo.max_cur_x;
120552862Sralph 	pmu.scrInfo.cursor.x = x;		/* keep track of real cursor */
120652862Sralph 	pmu.scrInfo.cursor.y = y;		/* position, indep. of mouse */
120752862Sralph 	pcc->xpos = PCC_X_OFFSET + x;
120852862Sralph 	pcc->ypos = PCC_Y_OFFSET + y;
120952862Sralph }
121052130Smckusick #endif
1211