xref: /csrg-svn/sys/pmax/dev/pm.c (revision 52862)
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*52862Sralph  *	@(#)pm.c	7.3 (Berkeley) 03/07/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"
47*52862Sralph #include "pmreg.h"
4852130Smckusick #include "font.c"
4952130Smckusick 
50*52862Sralph #define MAX_ROW	56
51*52862Sralph #define MAX_COL	80
52*52862Sralph 
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 */
62*52862Sralph 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  */
99*52862Sralph static void Scroll();
100*52862Sralph static void Blitc();
101*52862Sralph 
10252130Smckusick static void ScreenInit();
10352130Smckusick static void LoadCursor();
10452130Smckusick static void RestoreCursorColor();
10552130Smckusick static void CursorColor();
106*52862Sralph static void PosCursor();
10752130Smckusick static void InitColorMap();
10852130Smckusick static void VDACInit();
10952130Smckusick static void LoadColorMap();
110*52862Sralph static void EnableVideo();
111*52862Sralph static void DisableVideo();
11252130Smckusick 
11352130Smckusick extern void dcKBDPutc();
114*52862Sralph extern void (*dcDivertXInput)();
115*52862Sralph extern void (*dcMouseEvent)();
116*52862Sralph 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) {
409*52862Sralph 		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
418*52862Sralph 	 *  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 	 */
454*52862Sralph 	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 		 */
484*52862Sralph 		if (dcDebugGetc() == LK_HELP) {
485*52862Sralph 			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':
526*52862Sralph 		for (i = 8 - (col & 0x7); i > 0; i--)
52752130Smckusick 			Blitc(' ');
52852130Smckusick 		break;
52952130Smckusick 
53052130Smckusick 	case '\r':
531*52862Sralph 		col = 0;
53252130Smckusick 		break;
53352130Smckusick 
53452130Smckusick 	case '\b':
535*52862Sralph 		col--;
536*52862Sralph 		if (col < 0)
537*52862Sralph 			col = 0;
53852130Smckusick 		break;
53952130Smckusick 
54052130Smckusick 	case '\n':
541*52862Sralph 		if (row + 1 >= MAX_ROW)
54252130Smckusick 			Scroll();
54352130Smckusick 		else
544*52862Sralph 			row++;
545*52862Sralph 		col = 0;
54652130Smckusick 		break;
54752130Smckusick 
54852130Smckusick 	case '\007':
54952130Smckusick 		dcKBDPutc(LK_RING_BELL);
55052130Smckusick 		break;
55152130Smckusick 
55252130Smckusick 	default:
55352130Smckusick 		/*
554*52862Sralph 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
555*52862Sralph 		 * support.
556*52862Sralph 		 */
557*52862Sralph 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
558*52862Sralph 			break;
559*52862Sralph 		/*
56052130Smckusick 		 * If the next character will wrap around then
56152130Smckusick 		 * increment row counter or scroll screen.
56252130Smckusick 		 */
563*52862Sralph 		if (col >= MAX_COL) {
564*52862Sralph 			col = 0;
565*52862Sralph 			if (row + 1 >= MAX_ROW)
56652130Smckusick 				Scroll();
56752130Smckusick 			else
568*52862Sralph 				row++;
56952130Smckusick 		}
57052130Smckusick 		bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR +
571*52862Sralph 			(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 		}
629*52862Sralph 		col++; /* increment column counter */
63052130Smckusick 	}
63152130Smckusick 	if (!GraphicsOpen)
632*52862Sralph 		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 {
66552130Smckusick 
66652130Smckusick 	if (!GraphicsOpen)
66752130Smckusick 		return (EBADF);
66852130Smckusick 
66952130Smckusick 	GraphicsOpen = 0;
67052130Smckusick 	if (!isMono)
67152130Smckusick 		InitColorMap();
67252130Smckusick 	ScreenInit();
67352130Smckusick 	vmUserUnmap();
674*52862Sralph 	bzero((caddr_t)MACH_UNCACHED_FRAME_BUFFER_ADDR,
675*52862Sralph 		(isMono ? 1024 / 8 : 1024) * 864);
676*52862Sralph 	PosCursor(col * 8, row * 15);
67752130Smckusick 	return (0);
67852130Smckusick }
67952130Smckusick 
68052130Smckusick /*ARGSUSED*/
68152130Smckusick pmioctl(dev, cmd, data, flag)
68252130Smckusick 	dev_t dev;
68352130Smckusick 	caddr_t data;
68452130Smckusick {
68552130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
68652130Smckusick 
68752130Smckusick 	switch (cmd) {
68852130Smckusick 	case QIOCGINFO:
68952130Smckusick 	    {
69052130Smckusick 		caddr_t addr;
69152130Smckusick 		extern caddr_t vmUserMap();
69252130Smckusick 
69352130Smckusick 		/*
69452130Smckusick 		 * Map the all the data the user needs access to into
69552130Smckusick 		 * user space.
69652130Smckusick 		 */
69752130Smckusick 		addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
69852130Smckusick 		if (addr == (caddr_t)0)
69952130Smckusick 			goto mapError;
70052130Smckusick 		*(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
70152130Smckusick 		pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
70252130Smckusick 		pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
70352130Smckusick 		/*
70452130Smckusick 		 * Map the plane mask into the user's address space.
70552130Smckusick 		 */
70652130Smckusick 		addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR);
70752130Smckusick 		if (addr == (caddr_t)0)
70852130Smckusick 			goto mapError;
70952130Smckusick 		pmu.scrInfo.planemask = (char *)addr;
71052130Smckusick 		/*
711*52862Sralph 		 * Map the frame buffer into the user's address space.
71252130Smckusick 		 */
71352130Smckusick 		addr = vmUserMap(isMono ? 256*1024 : 1024*1024,
71452130Smckusick 			(unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR);
71552130Smckusick 		if (addr == (caddr_t)0)
71652130Smckusick 			goto mapError;
71752130Smckusick 		pmu.scrInfo.bitmap = (char *)addr;
71852130Smckusick 		break;
71952130Smckusick 
72052130Smckusick 	mapError:
72152130Smckusick 		vmUserUnmap();
72252130Smckusick 		printf("Cannot map shared data structures\n");
72352130Smckusick 		return (EIO);
72452130Smckusick 	    }
72552130Smckusick 
72652130Smckusick 	case QIOCPMSTATE:
72752130Smckusick 		/*
72852130Smckusick 		 * Set mouse state.
72952130Smckusick 		 */
73052130Smckusick 		pmu.scrInfo.mouse = *(pmCursor *)data;
73152130Smckusick 		PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
73252130Smckusick 		break;
73352130Smckusick 
73452130Smckusick 	case QIOCINIT:
73552130Smckusick 		/*
73652130Smckusick 		 * Initialize the screen.
73752130Smckusick 		 */
73852130Smckusick 		ScreenInit();
73952130Smckusick 		break;
74052130Smckusick 
74152130Smckusick 	case QIOCKPCMD:
74252130Smckusick 	    {
74352130Smckusick 		pmKpCmd *kpCmdPtr;
74452130Smckusick 		unsigned char *cp;
74552130Smckusick 
74652130Smckusick 		kpCmdPtr = (pmKpCmd *)data;
74752130Smckusick 		if (kpCmdPtr->nbytes == 0)
74852130Smckusick 			kpCmdPtr->cmd |= 0x80;
74952130Smckusick 		if (!GraphicsOpen)
75052130Smckusick 			kpCmdPtr->cmd |= 1;
75152130Smckusick 		dcKBDPutc((int)kpCmdPtr->cmd);
75252130Smckusick 		cp = &kpCmdPtr->par[0];
75352130Smckusick 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
75452130Smckusick 			if (kpCmdPtr->nbytes == 1)
75552130Smckusick 				*cp |= 0x80;
75652130Smckusick 			dcKBDPutc((int)*cp);
75752130Smckusick 		}
75852130Smckusick 		break;
75952130Smckusick 	    }
76052130Smckusick 
76152130Smckusick 	case QIOCADDR:
76252130Smckusick 		*(PM_Info **)data = &pmu.scrInfo;
76352130Smckusick 		break;
76452130Smckusick 
76552130Smckusick 	case QIOWCURSOR:
76652130Smckusick 		LoadCursor((unsigned short *)data);
76752130Smckusick 		break;
76852130Smckusick 
76952130Smckusick 	case QIOWCURSORCOLOR:
77052130Smckusick 		CursorColor((unsigned int *)data);
77152130Smckusick 		break;
77252130Smckusick 
77352130Smckusick 	case QIOSETCMAP:
77452130Smckusick 		LoadColorMap((ColorMap *)data);
77552130Smckusick 		break;
77652130Smckusick 
77752130Smckusick 	case QIOKERNLOOP:
778*52862Sralph 		dcDivertXInput = pmKbdEvent;
779*52862Sralph 		dcMouseEvent = pmMouseEvent;
780*52862Sralph 		dcMouseButtons = pmMouseButtons;
78152130Smckusick 		break;
78252130Smckusick 
78352130Smckusick 	case QIOKERNUNLOOP:
784*52862Sralph 		dcDivertXInput = (void (*)())0;
785*52862Sralph 		dcMouseEvent = (void (*)())0;
786*52862Sralph 		dcMouseButtons = (void (*)())0;
78752130Smckusick 		break;
78852130Smckusick 
78952130Smckusick 	case QIOVIDEOON:
79052130Smckusick 		if (!isMono)
79152130Smckusick 			RestoreCursorColor();
79252130Smckusick 		curReg |= PCC_ENPA;
79352130Smckusick 		curReg &= ~PCC_FOPB;
79452130Smckusick 		pcc->cmdr = curReg;
79552130Smckusick 		break;
79652130Smckusick 
79752130Smckusick 	case QIOVIDEOOFF:
79852130Smckusick 		if (!isMono)
79952130Smckusick 			VDACInit();
80052130Smckusick 		curReg |= PCC_FOPB;
80152130Smckusick 		curReg &= ~PCC_ENPA;
80252130Smckusick 		pcc->cmdr = curReg;
80352130Smckusick 		break;
80452130Smckusick 
80552130Smckusick 	default:
806*52862Sralph 		printf("pm0: Unknown ioctl command %x\n", cmd);
80752130Smckusick 		return (EINVAL);
80852130Smckusick 	}
80952130Smckusick 	return (0);
81052130Smckusick }
81152130Smckusick 
81252675Smckusick pmselect(dev, flag, p)
81352130Smckusick 	dev_t dev;
81452130Smckusick 	int flag;
81552675Smckusick 	struct proc *p;
81652130Smckusick {
81752130Smckusick 
81852130Smckusick 	switch (flag) {
81952130Smckusick 	case FREAD:
82052130Smckusick 		if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
82152130Smckusick 			return (1);
82252675Smckusick 		selrecord(p, &pm_selp);
82352130Smckusick 		break;
82452130Smckusick 	}
82552130Smckusick 
82652130Smckusick 	return (0);
82752130Smckusick }
828*52862Sralph 
829*52862Sralph static u_char	bg_RGB[3];	/* background color for the cursor */
830*52862Sralph static u_char	fg_RGB[3];	/* foreground color for the cursor */
831*52862Sralph 
832*52862Sralph /*
833*52862Sralph  * The default cursor.
834*52862Sralph  */
835*52862Sralph unsigned short defCursor[32] = {
836*52862Sralph /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
837*52862Sralph 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
838*52862Sralph /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
839*52862Sralph               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
840*52862Sralph 
841*52862Sralph };
842*52862Sralph 
843*52862Sralph /*
844*52862Sralph  * Test to see if device is present.
845*52862Sralph  * Return true if found and initialized ok.
846*52862Sralph  */
847*52862Sralph pminit()
848*52862Sralph {
849*52862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
850*52862Sralph 
851*52862Sralph 	isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO;
852*52862Sralph 	if (isMono) {
853*52862Sralph 		/* check for no frame buffer */
854*52862Sralph 		if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4))
855*52862Sralph 			return (0);
856*52862Sralph 	}
857*52862Sralph 
858*52862Sralph 	/*
859*52862Sralph 	 * Initialize the screen.
860*52862Sralph 	 */
861*52862Sralph 	pcc->cmdr = PCC_FOPB | PCC_VBHI;
862*52862Sralph 
863*52862Sralph 	/*
864*52862Sralph 	 * Initialize the cursor register.
865*52862Sralph 	 */
866*52862Sralph 	pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB;
867*52862Sralph 
868*52862Sralph 	/*
869*52862Sralph 	 * Initialize screen info.
870*52862Sralph 	 */
871*52862Sralph 	pmu.scrInfo.max_row = 56;
872*52862Sralph 	pmu.scrInfo.max_col = 80;
873*52862Sralph 	pmu.scrInfo.max_x = 1024;
874*52862Sralph 	pmu.scrInfo.max_y = 864;
875*52862Sralph 	pmu.scrInfo.max_cur_x = 1023;
876*52862Sralph 	pmu.scrInfo.max_cur_y = 863;
877*52862Sralph 	pmu.scrInfo.version = 11;
878*52862Sralph 	pmu.scrInfo.mthreshold = 4;
879*52862Sralph 	pmu.scrInfo.mscale = 2;
880*52862Sralph 	pmu.scrInfo.min_cur_x = -15;
881*52862Sralph 	pmu.scrInfo.min_cur_y = -15;
882*52862Sralph 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
883*52862Sralph 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
884*52862Sralph 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
885*52862Sralph 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
886*52862Sralph 	pmu.scrInfo.qe.tcNext = 0;
887*52862Sralph 
888*52862Sralph 	/*
889*52862Sralph 	 * Initialize the color map, the screen, and the mouse.
890*52862Sralph 	 */
891*52862Sralph 	InitColorMap();
892*52862Sralph 	ScreenInit();
893*52862Sralph 	Scroll();
894*52862Sralph 
895*52862Sralph 	initialized = 1;
896*52862Sralph 	return (1);
897*52862Sralph }
898*52862Sralph 
899*52862Sralph /*
900*52862Sralph  * ----------------------------------------------------------------------------
901*52862Sralph  *
902*52862Sralph  * ScreenInit --
903*52862Sralph  *
904*52862Sralph  *	Initialize the screen.
905*52862Sralph  *
906*52862Sralph  * Results:
907*52862Sralph  *	None.
908*52862Sralph  *
909*52862Sralph  * Side effects:
910*52862Sralph  *	The screen is initialized.
911*52862Sralph  *
912*52862Sralph  * ----------------------------------------------------------------------------
913*52862Sralph  */
914*52862Sralph static void
915*52862Sralph ScreenInit()
916*52862Sralph {
917*52862Sralph 
918*52862Sralph 	/*
919*52862Sralph 	 * Home the cursor.
920*52862Sralph 	 * We want an LSI terminal emulation.  We want the graphics
921*52862Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
922*52862Sralph 	 */
923*52862Sralph 	row = 55;
924*52862Sralph 	col = 0;
925*52862Sralph 
926*52862Sralph 	/*
927*52862Sralph 	 * Load the cursor with the default values
928*52862Sralph 	 *
929*52862Sralph 	 */
930*52862Sralph 	LoadCursor(defCursor);
931*52862Sralph }
932*52862Sralph 
933*52862Sralph /*
934*52862Sralph  * ----------------------------------------------------------------------------
935*52862Sralph  *
936*52862Sralph  * LoadCursor --
937*52862Sralph  *
938*52862Sralph  *	Routine to load the cursor Sprite pattern.
939*52862Sralph  *
940*52862Sralph  * Results:
941*52862Sralph  *	None.
942*52862Sralph  *
943*52862Sralph  * Side effects:
944*52862Sralph  *	The cursor is loaded into the hardware cursor.
945*52862Sralph  *
946*52862Sralph  * ----------------------------------------------------------------------------
947*52862Sralph  */
948*52862Sralph static void
949*52862Sralph LoadCursor(cur)
950*52862Sralph 	unsigned short *cur;
951*52862Sralph {
952*52862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
953*52862Sralph 	register int i;
954*52862Sralph 
955*52862Sralph 	curReg |= PCC_LODSA;
956*52862Sralph 	pcc->cmdr = curReg;
957*52862Sralph 	for (i = 0; i < 32; i++) {
958*52862Sralph 		pcc->memory = cur[i];
959*52862Sralph 		MachEmptyWriteBuffer();
960*52862Sralph 	}
961*52862Sralph 	curReg &= ~PCC_LODSA;
962*52862Sralph 	pcc->cmdr = curReg;
963*52862Sralph }
964*52862Sralph 
965*52862Sralph /*
966*52862Sralph  * ----------------------------------------------------------------------------
967*52862Sralph  *
968*52862Sralph  * RestoreCursorColor --
969*52862Sralph  *
970*52862Sralph  *	Routine to restore the color of the cursor.
971*52862Sralph  *
972*52862Sralph  * Results:
973*52862Sralph  *	None.
974*52862Sralph  *
975*52862Sralph  * Side effects:
976*52862Sralph  *	None.
977*52862Sralph  *
978*52862Sralph  * ----------------------------------------------------------------------------
979*52862Sralph  */
980*52862Sralph static void
981*52862Sralph RestoreCursorColor()
982*52862Sralph {
983*52862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
984*52862Sralph 	register int i;
985*52862Sralph 
986*52862Sralph 	vdac->overWA = 0x04;
987*52862Sralph 	MachEmptyWriteBuffer();
988*52862Sralph 	for (i = 0; i < 3; i++) {
989*52862Sralph 		vdac->over = bg_RGB[i];
990*52862Sralph 		MachEmptyWriteBuffer();
991*52862Sralph 	}
992*52862Sralph 
993*52862Sralph 	vdac->overWA = 0x08;
994*52862Sralph 	MachEmptyWriteBuffer();
995*52862Sralph 	vdac->over = 0x00;
996*52862Sralph 	MachEmptyWriteBuffer();
997*52862Sralph 	vdac->over = 0x00;
998*52862Sralph 	MachEmptyWriteBuffer();
999*52862Sralph 	vdac->over = 0x7f;
1000*52862Sralph 	MachEmptyWriteBuffer();
1001*52862Sralph 
1002*52862Sralph 	vdac->overWA = 0x0c;
1003*52862Sralph 	MachEmptyWriteBuffer();
1004*52862Sralph 	for (i = 0; i < 3; i++) {
1005*52862Sralph 		vdac->over = fg_RGB[i];
1006*52862Sralph 		MachEmptyWriteBuffer();
1007*52862Sralph 	}
1008*52862Sralph }
1009*52862Sralph 
1010*52862Sralph /*
1011*52862Sralph  * ----------------------------------------------------------------------------
1012*52862Sralph  *
1013*52862Sralph  * CursorColor --
1014*52862Sralph  *
1015*52862Sralph  *	Set the color of the cursor.
1016*52862Sralph  *
1017*52862Sralph  * Results:
1018*52862Sralph  *	None.
1019*52862Sralph  *
1020*52862Sralph  * Side effects:
1021*52862Sralph  *	None.
1022*52862Sralph  *
1023*52862Sralph  * ----------------------------------------------------------------------------
1024*52862Sralph  */
1025*52862Sralph static void
1026*52862Sralph CursorColor(color)
1027*52862Sralph 	unsigned int color[];
1028*52862Sralph {
1029*52862Sralph 	register int i, j;
1030*52862Sralph 
1031*52862Sralph 	for (i = 0; i < 3; i++)
1032*52862Sralph 		bg_RGB[i] = (u_char)(color[i] >> 8);
1033*52862Sralph 
1034*52862Sralph 	for (i = 3, j = 0; i < 6; i++, j++)
1035*52862Sralph 		fg_RGB[j] = (u_char)(color[i] >> 8);
1036*52862Sralph 
1037*52862Sralph 	RestoreCursorColor();
1038*52862Sralph }
1039*52862Sralph 
1040*52862Sralph /*
1041*52862Sralph  * ----------------------------------------------------------------------------
1042*52862Sralph  *
1043*52862Sralph  * InitColorMap --
1044*52862Sralph  *
1045*52862Sralph  *	Initialize the color map.
1046*52862Sralph  *
1047*52862Sralph  * Results:
1048*52862Sralph  *	None.
1049*52862Sralph  *
1050*52862Sralph  * Side effects:
1051*52862Sralph  *	The colormap is initialized appropriately whether it is color or
1052*52862Sralph  *	monochrome.
1053*52862Sralph  *
1054*52862Sralph  * ----------------------------------------------------------------------------
1055*52862Sralph  */
1056*52862Sralph static void
1057*52862Sralph InitColorMap()
1058*52862Sralph {
1059*52862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
1060*52862Sralph 	register int i;
1061*52862Sralph 
1062*52862Sralph 	*(char *)MACH_PLANE_MASK_ADDR = 0xff;
1063*52862Sralph 	MachEmptyWriteBuffer();
1064*52862Sralph 
1065*52862Sralph 	if (isMono) {
1066*52862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
1067*52862Sralph 		for (i = 0; i < 256; i++) {
1068*52862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
1069*52862Sralph 			MachEmptyWriteBuffer();
1070*52862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
1071*52862Sralph 			MachEmptyWriteBuffer();
1072*52862Sralph 			vdac->map = (i < 128) ? 0x00 : 0xff;
1073*52862Sralph 			MachEmptyWriteBuffer();
1074*52862Sralph 		}
1075*52862Sralph 	} else {
1076*52862Sralph 		vdac->mapWA = 0; MachEmptyWriteBuffer();
1077*52862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
1078*52862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
1079*52862Sralph 		vdac->map = 0; MachEmptyWriteBuffer();
1080*52862Sralph 
1081*52862Sralph 		for (i = 1; i < 256; i++) {
1082*52862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
1083*52862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
1084*52862Sralph 			vdac->map = 0xff; MachEmptyWriteBuffer();
1085*52862Sralph 		}
1086*52862Sralph 	}
1087*52862Sralph 
1088*52862Sralph 	for (i = 0; i < 3; i++) {
1089*52862Sralph 		bg_RGB[i] = 0x00;
1090*52862Sralph 		fg_RGB[i] = 0xff;
1091*52862Sralph 	}
1092*52862Sralph 	RestoreCursorColor();
1093*52862Sralph }
1094*52862Sralph 
1095*52862Sralph /*
1096*52862Sralph  * ----------------------------------------------------------------------------
1097*52862Sralph  *
1098*52862Sralph  * VDACInit --
1099*52862Sralph  *
1100*52862Sralph  *	Initialize the VDAC.
1101*52862Sralph  *
1102*52862Sralph  * Results:
1103*52862Sralph  *	None.
1104*52862Sralph  *
1105*52862Sralph  * Side effects:
1106*52862Sralph  *	None.
1107*52862Sralph  *
1108*52862Sralph  * ----------------------------------------------------------------------------
1109*52862Sralph  */
1110*52862Sralph static void
1111*52862Sralph VDACInit()
1112*52862Sralph {
1113*52862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
1114*52862Sralph 
1115*52862Sralph 	/*
1116*52862Sralph 	 *
1117*52862Sralph 	 * Initialize the VDAC
1118*52862Sralph 	 */
1119*52862Sralph 	vdac->overWA = 0x04; MachEmptyWriteBuffer();
1120*52862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
1121*52862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
1122*52862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
1123*52862Sralph 	vdac->overWA = 0x08; MachEmptyWriteBuffer();
1124*52862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
1125*52862Sralph 	vdac->over = 0x00; MachEmptyWriteBuffer();
1126*52862Sralph 	vdac->over = 0x7f; MachEmptyWriteBuffer();
1127*52862Sralph 	vdac->overWA = 0x0c; MachEmptyWriteBuffer();
1128*52862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
1129*52862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
1130*52862Sralph 	vdac->over = 0xff; MachEmptyWriteBuffer();
1131*52862Sralph }
1132*52862Sralph 
1133*52862Sralph /*
1134*52862Sralph  * ----------------------------------------------------------------------------
1135*52862Sralph  *
1136*52862Sralph  * LoadColorMap --
1137*52862Sralph  *
1138*52862Sralph  *	Load the color map.
1139*52862Sralph  *
1140*52862Sralph  * Results:
1141*52862Sralph  *	None.
1142*52862Sralph  *
1143*52862Sralph  * Side effects:
1144*52862Sralph  *	The color map is loaded.
1145*52862Sralph  *
1146*52862Sralph  * ----------------------------------------------------------------------------
1147*52862Sralph  */
1148*52862Sralph static void
1149*52862Sralph LoadColorMap(ptr)
1150*52862Sralph 	ColorMap *ptr;
1151*52862Sralph {
1152*52862Sralph 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
1153*52862Sralph 
1154*52862Sralph 	if (ptr->index > 256)
1155*52862Sralph 		return;
1156*52862Sralph 
1157*52862Sralph 	vdac->mapWA = ptr->index; MachEmptyWriteBuffer();
1158*52862Sralph 	vdac->map = ptr->Entry.red; MachEmptyWriteBuffer();
1159*52862Sralph 	vdac->map = ptr->Entry.green; MachEmptyWriteBuffer();
1160*52862Sralph 	vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer();
1161*52862Sralph }
1162*52862Sralph 
1163*52862Sralph /*
1164*52862Sralph  *----------------------------------------------------------------------
1165*52862Sralph  *
1166*52862Sralph  * PosCursor --
1167*52862Sralph  *
1168*52862Sralph  *	Postion the cursor.
1169*52862Sralph  *
1170*52862Sralph  * Results:
1171*52862Sralph  *	None.
1172*52862Sralph  *
1173*52862Sralph  * Side effects:
1174*52862Sralph  *	None.
1175*52862Sralph  *
1176*52862Sralph  *----------------------------------------------------------------------
1177*52862Sralph  */
1178*52862Sralph static void
1179*52862Sralph PosCursor(x, y)
1180*52862Sralph 	register int x, y;
1181*52862Sralph {
1182*52862Sralph 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
1183*52862Sralph 
1184*52862Sralph 	if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
1185*52862Sralph 		y = pmu.scrInfo.max_cur_y;
1186*52862Sralph 	if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
1187*52862Sralph 		x = pmu.scrInfo.max_cur_x;
1188*52862Sralph 	pmu.scrInfo.cursor.x = x;		/* keep track of real cursor */
1189*52862Sralph 	pmu.scrInfo.cursor.y = y;		/* position, indep. of mouse */
1190*52862Sralph 	pcc->xpos = PCC_X_OFFSET + x;
1191*52862Sralph 	pcc->ypos = PCC_Y_OFFSET + y;
1192*52862Sralph }
119352130Smckusick #endif
1194