xref: /csrg-svn/sys/pmax/dev/pm.c (revision 52675)
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*52675Smckusick  *	@(#)pm.c	7.2 (Berkeley) 02/26/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 #include "machine/pmreg.h"
4652130Smckusick 
4752130Smckusick #include "device.h"
4852130Smckusick #include "font.c"
4952130Smckusick 
5052130Smckusick /*
5152130Smckusick  * Macro to translate from a time struct to milliseconds.
5252130Smckusick  */
5352130Smckusick #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000))
5452130Smckusick 
5552130Smckusick static u_short	curReg;		/* copy of PCCRegs.cmdr since it's read only */
5652130Smckusick static int	isMono;		/* true if B&W frame buffer */
5752130Smckusick static int	initialized;	/* true if 'probe' was successful */
5852130Smckusick static int	GraphicsOpen;	/* true if the graphics device is open */
59*52675Smckusick static struct	selinfo pm_selp;/* process waiting for select */
6052130Smckusick 
6152130Smckusick /*
6252130Smckusick  * These need to be mapped into user space.
6352130Smckusick  */
6452130Smckusick static struct pmuaccess {
6552130Smckusick 	PM_Info		scrInfo;
6652130Smckusick 	pmEvent		events[PM_MAXEVQ];
6752130Smckusick 	pmTimeCoord	tcs[MOTION_BUFFER_SIZE];
6852130Smckusick } pmu;
6952130Smckusick 
7052130Smckusick static u_char	bg_RGB[3];	/* background color for the cursor */
7152130Smckusick static u_char	fg_RGB[3];	/* foreground color for the cursor */
7252130Smckusick 
7352130Smckusick /*
7452130Smckusick  * The default cursor.
7552130Smckusick  */
7652130Smckusick unsigned short defCursor[32] = {
7752130Smckusick /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
7852130Smckusick 	      0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
7952130Smckusick /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
8052130Smckusick               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
8152130Smckusick 
8252130Smckusick };
8352130Smckusick 
8452130Smckusick /*
8552130Smckusick  * Font mask bits used by Blitc().
8652130Smckusick  */
8752130Smckusick static unsigned int fontmaskBits[16] = {
8852130Smckusick 	0x00000000,
8952130Smckusick 	0x00000001,
9052130Smckusick 	0x00000100,
9152130Smckusick 	0x00000101,
9252130Smckusick 	0x00010000,
9352130Smckusick 	0x00010001,
9452130Smckusick 	0x00010100,
9552130Smckusick 	0x00010101,
9652130Smckusick 	0x01000000,
9752130Smckusick 	0x01000001,
9852130Smckusick 	0x01000100,
9952130Smckusick 	0x01000101,
10052130Smckusick 	0x01010000,
10152130Smckusick 	0x01010001,
10252130Smckusick 	0x01010100,
10352130Smckusick 	0x01010101
10452130Smckusick };
10552130Smckusick 
10652130Smckusick /*
10752130Smckusick  * Forward references.
10852130Smckusick  */
10952130Smckusick static void ScreenInit();
11052130Smckusick static void LoadCursor();
11152130Smckusick static void RestoreCursorColor();
11252130Smckusick static void CursorColor();
11352130Smckusick static void InitColorMap();
11452130Smckusick static void VDACInit();
11552130Smckusick static void LoadColorMap();
11652130Smckusick static void PosCursor();
11752130Smckusick static void Scroll();
11852130Smckusick static void Blitc();
11952130Smckusick 
12052130Smckusick extern void dcKBDPutc();
12152130Smckusick 
12252130Smckusick int	pmprobe();
12352130Smckusick struct	driver pmdriver = {
12452130Smckusick 	"pm", pmprobe, 0, 0,
12552130Smckusick };
12652130Smckusick 
12752130Smckusick /*
12852130Smckusick  * Test to see if device is present.
12952130Smckusick  * Return true if found and initialized ok.
13052130Smckusick  */
13152130Smckusick /*ARGSUSED*/
13252130Smckusick pmprobe(cp)
13352130Smckusick 	register struct pmax_ctlr *cp;
13452130Smckusick {
13552130Smckusick 
13652130Smckusick 	if (!initialized && !pminit())
13752130Smckusick 		return (0);
13852130Smckusick 	if (isMono)
13952130Smckusick 		printf("pm0 (monochrome display)\n");
14052130Smckusick 	else
14152130Smckusick 		printf("pm0 (color display)\n");
14252130Smckusick 	return (1);
14352130Smckusick }
14452130Smckusick 
14552130Smckusick /*
14652130Smckusick  * Test to see if device is present.
14752130Smckusick  * Return true if found and initialized ok.
14852130Smckusick  */
14952130Smckusick pminit()
15052130Smckusick {
15152130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
15252130Smckusick 
15352130Smckusick 	isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO;
15452130Smckusick 	if (isMono) {
15552130Smckusick 		/* check for no frame buffer */
15652130Smckusick 		if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4))
15752130Smckusick 			return (0);
15852130Smckusick 	}
15952130Smckusick 
16052130Smckusick 	/*
16152130Smckusick 	 * Initialize the screen.
16252130Smckusick 	 */
16352130Smckusick #ifdef notdef
16452130Smckusick 	DELAY(100000);		/* why? */
16552130Smckusick #endif
16652130Smckusick 	pcc->cmdr = PCC_FOPB | PCC_VBHI;
16752130Smckusick 
16852130Smckusick 	/*
16952130Smckusick 	 * Initialize the cursor register.
17052130Smckusick 	 */
17152130Smckusick 	pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB;
17252130Smckusick 
17352130Smckusick 	/*
17452130Smckusick 	 * Initialize screen info.
17552130Smckusick 	 */
17652130Smckusick 	pmu.scrInfo.max_row = 56;
17752130Smckusick 	pmu.scrInfo.max_col = 80;
17852130Smckusick 	pmu.scrInfo.max_x = 1024;
17952130Smckusick 	pmu.scrInfo.max_y = 864;
18052130Smckusick 	pmu.scrInfo.max_cur_x = 1023;
18152130Smckusick 	pmu.scrInfo.max_cur_y = 863;
18252130Smckusick 	pmu.scrInfo.version = 11;
18352130Smckusick 	pmu.scrInfo.mthreshold = 4;
18452130Smckusick 	pmu.scrInfo.mscale = 2;
18552130Smckusick 	pmu.scrInfo.min_cur_x = -15;
18652130Smckusick 	pmu.scrInfo.min_cur_y = -15;
18752130Smckusick 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
18852130Smckusick 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
18952130Smckusick 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
19052130Smckusick 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
19152130Smckusick 	pmu.scrInfo.qe.tcNext = 0;
19252130Smckusick 
19352130Smckusick 	/*
19452130Smckusick 	 * Initialize the color map, the screen, and the mouse.
19552130Smckusick 	 */
19652130Smckusick 	InitColorMap();
19752130Smckusick 	ScreenInit();
19852130Smckusick 	Scroll();
19952130Smckusick 
20052130Smckusick 	initialized = 1;
20152130Smckusick 	return (1);
20252130Smckusick }
20352130Smckusick 
20452130Smckusick /*
20552130Smckusick  * ----------------------------------------------------------------------------
20652130Smckusick  *
20752130Smckusick  * ScreenInit --
20852130Smckusick  *
20952130Smckusick  *	Initialize the screen.
21052130Smckusick  *
21152130Smckusick  * Results:
21252130Smckusick  *	None.
21352130Smckusick  *
21452130Smckusick  * Side effects:
21552130Smckusick  *	The screen is initialized.
21652130Smckusick  *
21752130Smckusick  * ----------------------------------------------------------------------------
21852130Smckusick  */
21952130Smckusick static void
22052130Smckusick ScreenInit()
22152130Smckusick {
22252130Smckusick 
22352130Smckusick 	/*
22452130Smckusick 	 * Home the cursor.
22552130Smckusick 	 * We want an LSI terminal emulation.  We want the graphics
22652130Smckusick 	 * terminal to scroll from the bottom. So start at the bottom.
22752130Smckusick 	 */
22852130Smckusick 	pmu.scrInfo.row = 55;
22952130Smckusick 	pmu.scrInfo.col = 0;
23052130Smckusick 
23152130Smckusick 	/*
23252130Smckusick 	 * Load the cursor with the default values
23352130Smckusick 	 *
23452130Smckusick 	 */
23552130Smckusick 	LoadCursor(defCursor);
23652130Smckusick }
23752130Smckusick 
23852130Smckusick /*
23952130Smckusick  * ----------------------------------------------------------------------------
24052130Smckusick  *
24152130Smckusick  * LoadCursor --
24252130Smckusick  *
24352130Smckusick  *	Routine to load the cursor Sprite pattern.
24452130Smckusick  *
24552130Smckusick  * Results:
24652130Smckusick  *	None.
24752130Smckusick  *
24852130Smckusick  * Side effects:
24952130Smckusick  *	The cursor is loaded into the hardware cursor.
25052130Smckusick  *
25152130Smckusick  * ----------------------------------------------------------------------------
25252130Smckusick  */
25352130Smckusick static void
25452130Smckusick LoadCursor(cur)
25552130Smckusick 	unsigned short *cur;
25652130Smckusick {
25752130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
25852130Smckusick 	register int i;
25952130Smckusick 
26052130Smckusick 	curReg |= PCC_LODSA;
26152130Smckusick 	pcc->cmdr = curReg;
26252130Smckusick 	for (i = 0; i < 32; i++) {
26352130Smckusick 		pcc->memory = cur[i];
26452130Smckusick 		MachEmptyWriteBuffer();
26552130Smckusick 	}
26652130Smckusick 	curReg &= ~PCC_LODSA;
26752130Smckusick 	pcc->cmdr = curReg;
26852130Smckusick }
26952130Smckusick 
27052130Smckusick /*
27152130Smckusick  * ----------------------------------------------------------------------------
27252130Smckusick  *
27352130Smckusick  * RestoreCursorColor --
27452130Smckusick  *
27552130Smckusick  *	Routine to restore the color of the cursor.
27652130Smckusick  *
27752130Smckusick  * Results:
27852130Smckusick  *	None.
27952130Smckusick  *
28052130Smckusick  * Side effects:
28152130Smckusick  *	None.
28252130Smckusick  *
28352130Smckusick  * ----------------------------------------------------------------------------
28452130Smckusick  */
28552130Smckusick static void
28652130Smckusick RestoreCursorColor()
28752130Smckusick {
28852130Smckusick 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
28952130Smckusick 	register int i;
29052130Smckusick 
29152130Smckusick 	vdac->overWA = 0x04;
29252130Smckusick 	MachEmptyWriteBuffer();
29352130Smckusick 	for (i = 0; i < 3; i++) {
29452130Smckusick 		vdac->over = bg_RGB[i];
29552130Smckusick 		MachEmptyWriteBuffer();
29652130Smckusick 	}
29752130Smckusick 
29852130Smckusick 	vdac->overWA = 0x08;
29952130Smckusick 	MachEmptyWriteBuffer();
30052130Smckusick 	vdac->over = 0x00;
30152130Smckusick 	MachEmptyWriteBuffer();
30252130Smckusick 	vdac->over = 0x00;
30352130Smckusick 	MachEmptyWriteBuffer();
30452130Smckusick 	vdac->over = 0x7f;
30552130Smckusick 	MachEmptyWriteBuffer();
30652130Smckusick 
30752130Smckusick 	vdac->overWA = 0x0c;
30852130Smckusick 	MachEmptyWriteBuffer();
30952130Smckusick 	for (i = 0; i < 3; i++) {
31052130Smckusick 		vdac->over = fg_RGB[i];
31152130Smckusick 		MachEmptyWriteBuffer();
31252130Smckusick 	}
31352130Smckusick }
31452130Smckusick 
31552130Smckusick /*
31652130Smckusick  * ----------------------------------------------------------------------------
31752130Smckusick  *
31852130Smckusick  * CursorColor --
31952130Smckusick  *
32052130Smckusick  *	Set the color of the cursor.
32152130Smckusick  *
32252130Smckusick  * Results:
32352130Smckusick  *	None.
32452130Smckusick  *
32552130Smckusick  * Side effects:
32652130Smckusick  *	None.
32752130Smckusick  *
32852130Smckusick  * ----------------------------------------------------------------------------
32952130Smckusick  */
33052130Smckusick static void
33152130Smckusick CursorColor(color)
33252130Smckusick 	unsigned int color[];
33352130Smckusick {
33452130Smckusick 	register int i, j;
33552130Smckusick 
33652130Smckusick 	for (i = 0; i < 3; i++)
33752130Smckusick 		bg_RGB[i] = (u_char)(color[i] >> 8);
33852130Smckusick 
33952130Smckusick 	for (i = 3, j = 0; i < 6; i++, j++)
34052130Smckusick 		fg_RGB[j] = (u_char)(color[i] >> 8);
34152130Smckusick 
34252130Smckusick 	RestoreCursorColor();
34352130Smckusick }
34452130Smckusick 
34552130Smckusick /*
34652130Smckusick  * ----------------------------------------------------------------------------
34752130Smckusick  *
34852130Smckusick  * InitColorMap --
34952130Smckusick  *
35052130Smckusick  *	Initialize the color map.
35152130Smckusick  *
35252130Smckusick  * Results:
35352130Smckusick  *	None.
35452130Smckusick  *
35552130Smckusick  * Side effects:
35652130Smckusick  *	The colormap is initialized appropriately whether it is color or
35752130Smckusick  *	monochrome.
35852130Smckusick  *
35952130Smckusick  * ----------------------------------------------------------------------------
36052130Smckusick  */
36152130Smckusick static void
36252130Smckusick InitColorMap()
36352130Smckusick {
36452130Smckusick 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
36552130Smckusick 	register int i;
36652130Smckusick 
36752130Smckusick 	*(char *)MACH_PLANE_MASK_ADDR = 0xff;
36852130Smckusick 	MachEmptyWriteBuffer();
36952130Smckusick 
37052130Smckusick 	if (isMono) {
37152130Smckusick 		vdac->mapWA = 0; MachEmptyWriteBuffer();
37252130Smckusick 		for (i = 0; i < 256; i++) {
37352130Smckusick 			vdac->map = (i < 128) ? 0x00 : 0xff;
37452130Smckusick 			MachEmptyWriteBuffer();
37552130Smckusick 			vdac->map = (i < 128) ? 0x00 : 0xff;
37652130Smckusick 			MachEmptyWriteBuffer();
37752130Smckusick 			vdac->map = (i < 128) ? 0x00 : 0xff;
37852130Smckusick 			MachEmptyWriteBuffer();
37952130Smckusick 		}
38052130Smckusick 	} else {
38152130Smckusick 		vdac->mapWA = 0; MachEmptyWriteBuffer();
38252130Smckusick 		vdac->map = 0; MachEmptyWriteBuffer();
38352130Smckusick 		vdac->map = 0; MachEmptyWriteBuffer();
38452130Smckusick 		vdac->map = 0; MachEmptyWriteBuffer();
38552130Smckusick 
38652130Smckusick 		for (i = 1; i < 256; i++) {
38752130Smckusick 			vdac->map = 0xff; MachEmptyWriteBuffer();
38852130Smckusick 			vdac->map = 0xff; MachEmptyWriteBuffer();
38952130Smckusick 			vdac->map = 0xff; MachEmptyWriteBuffer();
39052130Smckusick 		}
39152130Smckusick 	}
39252130Smckusick 
39352130Smckusick 	for (i = 0; i < 3; i++) {
39452130Smckusick 		bg_RGB[i] = 0x00;
39552130Smckusick 		fg_RGB[i] = 0xff;
39652130Smckusick 	}
39752130Smckusick 	RestoreCursorColor();
39852130Smckusick }
39952130Smckusick 
40052130Smckusick /*
40152130Smckusick  * ----------------------------------------------------------------------------
40252130Smckusick  *
40352130Smckusick  * VDACInit --
40452130Smckusick  *
40552130Smckusick  *	Initialize the VDAC.
40652130Smckusick  *
40752130Smckusick  * Results:
40852130Smckusick  *	None.
40952130Smckusick  *
41052130Smckusick  * Side effects:
41152130Smckusick  *	None.
41252130Smckusick  *
41352130Smckusick  * ----------------------------------------------------------------------------
41452130Smckusick  */
41552130Smckusick static void
41652130Smckusick VDACInit()
41752130Smckusick {
41852130Smckusick 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
41952130Smckusick 
42052130Smckusick 	/*
42152130Smckusick 	 *
42252130Smckusick 	 * Initialize the VDAC
42352130Smckusick 	 */
42452130Smckusick 	vdac->overWA = 0x04; MachEmptyWriteBuffer();
42552130Smckusick 	vdac->over = 0x00; MachEmptyWriteBuffer();
42652130Smckusick 	vdac->over = 0x00; MachEmptyWriteBuffer();
42752130Smckusick 	vdac->over = 0x00; MachEmptyWriteBuffer();
42852130Smckusick 	vdac->overWA = 0x08; MachEmptyWriteBuffer();
42952130Smckusick 	vdac->over = 0x00; MachEmptyWriteBuffer();
43052130Smckusick 	vdac->over = 0x00; MachEmptyWriteBuffer();
43152130Smckusick 	vdac->over = 0x7f; MachEmptyWriteBuffer();
43252130Smckusick 	vdac->overWA = 0x0c; MachEmptyWriteBuffer();
43352130Smckusick 	vdac->over = 0xff; MachEmptyWriteBuffer();
43452130Smckusick 	vdac->over = 0xff; MachEmptyWriteBuffer();
43552130Smckusick 	vdac->over = 0xff; MachEmptyWriteBuffer();
43652130Smckusick }
43752130Smckusick 
43852130Smckusick /*
43952130Smckusick  * ----------------------------------------------------------------------------
44052130Smckusick  *
44152130Smckusick  * LoadColorMap --
44252130Smckusick  *
44352130Smckusick  *	Load the color map.
44452130Smckusick  *
44552130Smckusick  * Results:
44652130Smckusick  *	None.
44752130Smckusick  *
44852130Smckusick  * Side effects:
44952130Smckusick  *	The color map is loaded.
45052130Smckusick  *
45152130Smckusick  * ----------------------------------------------------------------------------
45252130Smckusick  */
45352130Smckusick static void
45452130Smckusick LoadColorMap(ptr)
45552130Smckusick 	ColorMap *ptr;
45652130Smckusick {
45752130Smckusick 	register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR;
45852130Smckusick 
45952130Smckusick 	if (ptr->index > 256)
46052130Smckusick 		return;
46152130Smckusick 
46252130Smckusick 	vdac->mapWA = ptr->index; MachEmptyWriteBuffer();
46352130Smckusick 	vdac->map = ptr->Entry.red; MachEmptyWriteBuffer();
46452130Smckusick 	vdac->map = ptr->Entry.green; MachEmptyWriteBuffer();
46552130Smckusick 	vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer();
46652130Smckusick }
46752130Smckusick 
46852130Smckusick /*
46952130Smckusick  *----------------------------------------------------------------------
47052130Smckusick  *
47152130Smckusick  * pmKbdEvent --
47252130Smckusick  *
47352130Smckusick  *	Process a received character.
47452130Smckusick  *
47552130Smckusick  * Results:
47652130Smckusick  *	None.
47752130Smckusick  *
47852130Smckusick  * Side effects:
47952130Smckusick  *	Events added to the queue.
48052130Smckusick  *
48152130Smckusick  *----------------------------------------------------------------------
48252130Smckusick  */
48352130Smckusick void
48452130Smckusick pmKbdEvent(ch)
48552130Smckusick 	int ch;
48652130Smckusick {
48752130Smckusick 	register pmEvent *eventPtr;
48852130Smckusick 	int i;
48952130Smckusick 
49052130Smckusick 	if (!GraphicsOpen)
49152130Smckusick 		return;
49252130Smckusick 
49352130Smckusick 	/*
49452130Smckusick 	 * See if there is room in the queue.
49552130Smckusick 	 */
49652130Smckusick 	i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
49752130Smckusick 	if (i == pmu.scrInfo.qe.eHead)
49852130Smckusick 		return;
49952130Smckusick 
50052130Smckusick 	/*
50152130Smckusick 	 * Add the event to the queue.
50252130Smckusick 	 */
50352130Smckusick 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
50452130Smckusick 	eventPtr->type = BUTTON_RAW_TYPE;
50552130Smckusick 	eventPtr->device = KEYBOARD_DEVICE;
50652130Smckusick 	eventPtr->x = pmu.scrInfo.mouse.x;
50752130Smckusick 	eventPtr->y = pmu.scrInfo.mouse.y;
50852130Smckusick 	eventPtr->time = TO_MS(time);
50952130Smckusick 	eventPtr->key = ch;
51052130Smckusick 	pmu.scrInfo.qe.eTail = i;
511*52675Smckusick 	selwakeup(&pm_selp);
51252130Smckusick }
51352130Smckusick 
51452130Smckusick /*
51552130Smckusick  *----------------------------------------------------------------------
51652130Smckusick  *
51752130Smckusick  * pmMouseEvent --
51852130Smckusick  *
51952130Smckusick  *	Process a mouse event.
52052130Smckusick  *
52152130Smckusick  * Results:
52252130Smckusick  *	None.
52352130Smckusick  *
52452130Smckusick  * Side effects:
52552130Smckusick  *	An event is added to the event queue.
52652130Smckusick  *
52752130Smckusick  *----------------------------------------------------------------------
52852130Smckusick  */
52952130Smckusick void
53052130Smckusick pmMouseEvent(newRepPtr)
53152130Smckusick 	register MouseReport *newRepPtr;
53252130Smckusick {
53352130Smckusick 	unsigned milliSec;
53452130Smckusick 	int i;
53552130Smckusick 	pmEvent *eventPtr;
53652130Smckusick 
53752130Smckusick 	if (!GraphicsOpen)
53852130Smckusick 		return;
53952130Smckusick 
54052130Smckusick 	milliSec = TO_MS(time);
54152130Smckusick 
54252130Smckusick 	/*
54352130Smckusick 	 * Check to see if we have to accelerate the mouse
54452130Smckusick 	 */
54552130Smckusick 	if (pmu.scrInfo.mscale >= 0) {
54652130Smckusick 		if (newRepPtr->dx >= pmu.scrInfo.mthreshold) {
54752130Smckusick 			newRepPtr->dx +=
54852130Smckusick 				(newRepPtr->dx - pmu.scrInfo.mthreshold) *
54952130Smckusick 				pmu.scrInfo.mscale;
55052130Smckusick 		}
55152130Smckusick 		if (newRepPtr->dy >= pmu.scrInfo.mthreshold) {
55252130Smckusick 			newRepPtr->dy +=
55352130Smckusick 				(newRepPtr->dy - pmu.scrInfo.mthreshold) *
55452130Smckusick 				pmu.scrInfo.mscale;
55552130Smckusick 		}
55652130Smckusick 	}
55752130Smckusick 
55852130Smckusick 	/*
55952130Smckusick 	 * Update mouse position
56052130Smckusick 	 */
56152130Smckusick 	if (newRepPtr->state & MOUSE_X_SIGN) {
56252130Smckusick 		pmu.scrInfo.mouse.x += newRepPtr->dx;
56352130Smckusick 		if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x)
56452130Smckusick 			pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x;
56552130Smckusick 	} else {
56652130Smckusick 		pmu.scrInfo.mouse.x -= newRepPtr->dx;
56752130Smckusick 		if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x)
56852130Smckusick 			pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x;
56952130Smckusick 	}
57052130Smckusick 	if (newRepPtr->state & MOUSE_Y_SIGN) {
57152130Smckusick 		pmu.scrInfo.mouse.y -= newRepPtr->dy;
57252130Smckusick 		if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y)
57352130Smckusick 			pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y;
57452130Smckusick 	} else {
57552130Smckusick 		pmu.scrInfo.mouse.y += newRepPtr->dy;
57652130Smckusick 		if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y)
57752130Smckusick 			pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y;
57852130Smckusick 	}
57952130Smckusick 
58052130Smckusick 	/*
58152130Smckusick 	 * Move the hardware cursor.
58252130Smckusick 	 */
58352130Smckusick 	PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
58452130Smckusick 
58552130Smckusick 	/*
58652130Smckusick 	 * Store the motion event in the motion buffer.
58752130Smckusick 	 */
58852130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec;
58952130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x;
59052130Smckusick 	pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y;
59152130Smckusick 	if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE)
59252130Smckusick 		pmu.scrInfo.qe.tcNext = 0;
59352130Smckusick 	if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom &&
59452130Smckusick 	    pmu.scrInfo.mouse.y >=  pmu.scrInfo.mbox.top &&
59552130Smckusick 	    pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right &&
59652130Smckusick 	    pmu.scrInfo.mouse.x >=  pmu.scrInfo.mbox.left)
59752130Smckusick 		return;
59852130Smckusick 
59952130Smckusick 	pmu.scrInfo.mbox.bottom = 0;
60052130Smckusick 	if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead)
60152130Smckusick 		return;
60252130Smckusick 
60352130Smckusick 	i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1);
60452130Smckusick 	if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) &&
60552130Smckusick 	    (i != pmu.scrInfo.qe.eHead)) {
60652130Smckusick 		pmEvent *eventPtr;
60752130Smckusick 
60852130Smckusick 		eventPtr = &pmu.events[i];
60952130Smckusick 		if (eventPtr->type == MOTION_TYPE) {
61052130Smckusick 			eventPtr->x = pmu.scrInfo.mouse.x;
61152130Smckusick 			eventPtr->y = pmu.scrInfo.mouse.y;
61252130Smckusick 			eventPtr->time = milliSec;
61352130Smckusick 			eventPtr->device = MOUSE_DEVICE;
61452130Smckusick 			return;
61552130Smckusick 		}
61652130Smckusick 	}
61752130Smckusick 	/*
61852130Smckusick 	 * Put event into queue and wakeup any waiters.
61952130Smckusick 	 */
62052130Smckusick 	eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
62152130Smckusick 	eventPtr->type = MOTION_TYPE;
62252130Smckusick 	eventPtr->time = milliSec;
62352130Smckusick 	eventPtr->x = pmu.scrInfo.mouse.x;
62452130Smckusick 	eventPtr->y = pmu.scrInfo.mouse.y;
62552130Smckusick 	eventPtr->device = MOUSE_DEVICE;
62652130Smckusick 	pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1);
627*52675Smckusick 	selwakeup(&pm_selp);
62852130Smckusick }
62952130Smckusick 
63052130Smckusick /*
63152130Smckusick  *----------------------------------------------------------------------
63252130Smckusick  *
63352130Smckusick  * pmMouseButtons --
63452130Smckusick  *
63552130Smckusick  *	Process mouse buttons.
63652130Smckusick  *
63752130Smckusick  * Results:
63852130Smckusick  *	None.
63952130Smckusick  *
64052130Smckusick  * Side effects:
64152130Smckusick  *	None.
64252130Smckusick  *
64352130Smckusick  *----------------------------------------------------------------------
64452130Smckusick  */
64552130Smckusick void
64652130Smckusick pmMouseButtons(newRepPtr)
64752130Smckusick 	MouseReport *newRepPtr;
64852130Smckusick {
64952130Smckusick 	static char temp, oldSwitch, newSwitch;
65052130Smckusick 	int i, j;
65152130Smckusick 	pmEvent *eventPtr;
65252130Smckusick 	static MouseReport lastRep;
65352130Smckusick 
65452130Smckusick 	if (!GraphicsOpen)
65552130Smckusick 		return;
65652130Smckusick 
65752130Smckusick 	newSwitch = newRepPtr->state & 0x07;
65852130Smckusick 	oldSwitch = lastRep.state & 0x07;
65952130Smckusick 
66052130Smckusick 	temp = oldSwitch ^ newSwitch;
66152130Smckusick 	if (temp == 0)
66252130Smckusick 		return;
66352130Smckusick 	for (j = 1; j < 8; j <<= 1) {
66452130Smckusick 		if ((j & temp) == 0)
66552130Smckusick 			continue;
66652130Smckusick 
66752130Smckusick 		/*
66852130Smckusick 		 * Check for room in the queue
66952130Smckusick 		 */
67052130Smckusick 		i = PM_EVROUND(pmu.scrInfo.qe.eTail+1);
67152130Smckusick 		if (i == pmu.scrInfo.qe.eHead)
67252130Smckusick 			return;
67352130Smckusick 
67452130Smckusick 		/*
67552130Smckusick 		 * Put event into queue.
67652130Smckusick 		 */
67752130Smckusick 		eventPtr = &pmu.events[pmu.scrInfo.qe.eTail];
67852130Smckusick 
67952130Smckusick 		switch (j) {
68052130Smckusick 		case RIGHT_BUTTON:
68152130Smckusick 			eventPtr->key = EVENT_RIGHT_BUTTON;
68252130Smckusick 			break;
68352130Smckusick 
68452130Smckusick 		case MIDDLE_BUTTON:
68552130Smckusick 			eventPtr->key = EVENT_MIDDLE_BUTTON;
68652130Smckusick 			break;
68752130Smckusick 
68852130Smckusick 		case LEFT_BUTTON:
68952130Smckusick 			eventPtr->key = EVENT_LEFT_BUTTON;
69052130Smckusick 		}
69152130Smckusick 		if (newSwitch & j)
69252130Smckusick 			eventPtr->type = BUTTON_DOWN_TYPE;
69352130Smckusick 		else
69452130Smckusick 			eventPtr->type = BUTTON_UP_TYPE;
69552130Smckusick 		eventPtr->device = MOUSE_DEVICE;
69652130Smckusick 
69752130Smckusick 		eventPtr->time = TO_MS(time);
69852130Smckusick 		eventPtr->x = pmu.scrInfo.mouse.x;
69952130Smckusick 		eventPtr->y = pmu.scrInfo.mouse.y;
70052130Smckusick 	}
70152130Smckusick 	pmu.scrInfo.qe.eTail = i;
702*52675Smckusick 	selwakeup(&pm_selp);
70352130Smckusick 
70452130Smckusick 	lastRep = *newRepPtr;
70552130Smckusick 	pmu.scrInfo.mswitches = newSwitch;
70652130Smckusick }
70752130Smckusick 
70852130Smckusick /*
70952130Smckusick  *----------------------------------------------------------------------
71052130Smckusick  *
71152130Smckusick  * PosCursor --
71252130Smckusick  *
71352130Smckusick  *	Postion the cursor.
71452130Smckusick  *
71552130Smckusick  * Results:
71652130Smckusick  *	None.
71752130Smckusick  *
71852130Smckusick  * Side effects:
71952130Smckusick  *	None.
72052130Smckusick  *
72152130Smckusick  *----------------------------------------------------------------------
72252130Smckusick  */
72352130Smckusick static void
72452130Smckusick PosCursor(x, y)
72552130Smckusick 	register int x, y;
72652130Smckusick {
72752130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
72852130Smckusick 
72952130Smckusick 	if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y)
73052130Smckusick 		y = pmu.scrInfo.max_cur_y;
73152130Smckusick 	if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x)
73252130Smckusick 		x = pmu.scrInfo.max_cur_x;
73352130Smckusick 	pmu.scrInfo.cursor.x = x;		/* keep track of real cursor */
73452130Smckusick 	pmu.scrInfo.cursor.y = y;		/* position, indep. of mouse */
73552130Smckusick 	pcc->xpos = PCC_X_OFFSET + x;
73652130Smckusick 	pcc->ypos = PCC_Y_OFFSET + y;
73752130Smckusick }
73852130Smckusick 
73952130Smckusick /*
74052130Smckusick  *----------------------------------------------------------------------
74152130Smckusick  *
74252130Smckusick  * Scroll --
74352130Smckusick  *
74452130Smckusick  *	Scroll the screen.
74552130Smckusick  *
74652130Smckusick  * Results:
74752130Smckusick  *	None.
74852130Smckusick  *
74952130Smckusick  * Side effects:
75052130Smckusick  *	None.
75152130Smckusick  *
75252130Smckusick  *----------------------------------------------------------------------
75352130Smckusick  */
75452130Smckusick static void
75552130Smckusick Scroll()
75652130Smckusick {
75752130Smckusick 	register int *dest, *src;
75852130Smckusick 	register int *end;
75952130Smckusick 	register int temp0, temp1, temp2, temp3;
76052130Smckusick 	register int i, scanInc, lineCount;
76152130Smckusick 	int line;
76252130Smckusick 
76352130Smckusick 	/*
76452130Smckusick 	 * If the mouse is on we don't scroll so that the bit map remains sane.
76552130Smckusick 	 */
76652130Smckusick 	if (GraphicsOpen) {
76752130Smckusick 		pmu.scrInfo.row = 0;
76852130Smckusick 		return;
76952130Smckusick 	}
77052130Smckusick 
77152130Smckusick 	/*
77252130Smckusick 	 *  The following is an optimization to cause the scrolling
77352130Smckusick 	 *  of text to be memory limited.  Basically the writebuffer is
77452130Smckusick 	 *  4 words (32 bits ea.) long so to achieve maximum speed we
77552130Smckusick 	 *  read and write in multiples of 4 words. We also limit the
77652130Smckusick 	 *  size to be 80 characters for more speed.
77752130Smckusick 	 */
77852130Smckusick 	if (isMono) {
77952130Smckusick 		lineCount = 5;
78052130Smckusick 		line = 1920 * 2;
78152130Smckusick 		scanInc = 44;
78252130Smckusick 	} else {
78352130Smckusick 		lineCount = 40;
78452130Smckusick 		scanInc = 96;
78552130Smckusick 		line = 1920 * 8;
78652130Smckusick 	}
78752130Smckusick 	src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line);
78852130Smckusick 	dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR);
78952130Smckusick 	end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line);
79052130Smckusick 	do {
79152130Smckusick 		i = 0;
79252130Smckusick 		do {
79352130Smckusick 			temp0 = src[0];
79452130Smckusick 			temp1 = src[1];
79552130Smckusick 			temp2 = src[2];
79652130Smckusick 			temp3 = src[3];
79752130Smckusick 			dest[0] = temp0;
79852130Smckusick 			dest[1] = temp1;
79952130Smckusick 			dest[2] = temp2;
80052130Smckusick 			dest[3] = temp3;
80152130Smckusick 			dest += 4;
80252130Smckusick 			src += 4;
80352130Smckusick 			i++;
80452130Smckusick 		} while (i < lineCount);
80552130Smckusick 		src += scanInc;
80652130Smckusick 		dest += scanInc;
80752130Smckusick 	} while (src < end);
80852130Smckusick 
80952130Smckusick 	/*
81052130Smckusick 	 * Now zero out the last two lines
81152130Smckusick 	 */
81252130Smckusick 	bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (pmu.scrInfo.row * line),
81352130Smckusick 		3 * line);
81452130Smckusick }
81552130Smckusick 
81652130Smckusick /*
81752130Smckusick  *----------------------------------------------------------------------
81852130Smckusick  *
81952130Smckusick  * pmPutc --
82052130Smckusick  *
82152130Smckusick  *	Write a character to the console.
82252130Smckusick  *
82352130Smckusick  * Results:
82452130Smckusick  *	None.
82552130Smckusick  *
82652130Smckusick  * Side effects:
82752130Smckusick  *	None.
82852130Smckusick  *
82952130Smckusick  *----------------------------------------------------------------------
83052130Smckusick  */
83152130Smckusick pmPutc(c)
83252130Smckusick 	register int c;
83352130Smckusick {
83452130Smckusick 	int s;
83552130Smckusick 
83652130Smckusick 	s = splhigh();	/* in case we do any printf's at interrupt time */
83752130Smckusick 	if (initialized) {
83852130Smckusick #ifdef DEBUG
83952130Smckusick 		/*
84052130Smckusick 		 * If the HELP key is pressed, wait for another
84152130Smckusick 		 * HELP key press to start/stop output.
84252130Smckusick 		 */
84352130Smckusick 		if (dcKBDGetc() == LK_HELP) {
84452130Smckusick 			while (dcKBDGetc() != LK_HELP)
84552130Smckusick 				;
84652130Smckusick 		}
84752130Smckusick #endif
84852130Smckusick 		Blitc(c);
84952130Smckusick 	} else {
85052130Smckusick 		void (*f)() = (void (*)())MACH_MON_PUTCHAR;
85152130Smckusick 
85252130Smckusick 		(*f)(c);
85352130Smckusick 	}
85452130Smckusick 	splx(s);
85552130Smckusick }
85652130Smckusick 
85752130Smckusick /*
85852130Smckusick  *----------------------------------------------------------------------
85952130Smckusick  *
86052130Smckusick  * Blitc --
86152130Smckusick  *
86252130Smckusick  *	Write a character to the screen.
86352130Smckusick  *
86452130Smckusick  * Results:
86552130Smckusick  *	None.
86652130Smckusick  *
86752130Smckusick  * Side effects:
86852130Smckusick  *	None.
86952130Smckusick  *
87052130Smckusick  *----------------------------------------------------------------------
87152130Smckusick  */
87252130Smckusick static void
87352130Smckusick Blitc(c)
87452130Smckusick 	register int c;
87552130Smckusick {
87652130Smckusick 	register char *bRow, *fRow;
87752130Smckusick 	register int i;
87852130Smckusick 	register int ote = isMono ? 256 : 1024; /* offset to table entry */
87952130Smckusick 	int colMult = isMono ? 1 : 8;
88052130Smckusick 
88152130Smckusick 	c &= 0xff;
88252130Smckusick 
88352130Smckusick 	switch (c) {
88452130Smckusick 	case '\t':
88552130Smckusick 		for (i = 8 - (pmu.scrInfo.col & 0x7); i > 0; i--)
88652130Smckusick 			Blitc(' ');
88752130Smckusick 		break;
88852130Smckusick 
88952130Smckusick 	case '\r':
89052130Smckusick 		pmu.scrInfo.col = 0;
89152130Smckusick 		break;
89252130Smckusick 
89352130Smckusick 	case '\b':
89452130Smckusick 		pmu.scrInfo.col--;
89552130Smckusick 		if (pmu.scrInfo.col < 0)
89652130Smckusick 			pmu.scrInfo.col = 0;
89752130Smckusick 		break;
89852130Smckusick 
89952130Smckusick 	case '\n':
90052130Smckusick 		if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row)
90152130Smckusick 			Scroll();
90252130Smckusick 		else
90352130Smckusick 			pmu.scrInfo.row++;
90452130Smckusick 		pmu.scrInfo.col = 0;
90552130Smckusick 		break;
90652130Smckusick 
90752130Smckusick 	case '\007':
90852130Smckusick 		dcKBDPutc(LK_RING_BELL);
90952130Smckusick 		break;
91052130Smckusick 
91152130Smckusick 	default:
91252130Smckusick 		/*
91352130Smckusick 		 * If the next character will wrap around then
91452130Smckusick 		 * increment row counter or scroll screen.
91552130Smckusick 		 */
91652130Smckusick 		if (pmu.scrInfo.col >= pmu.scrInfo.max_col) {
91752130Smckusick 			pmu.scrInfo.col = 0;
91852130Smckusick 			if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row)
91952130Smckusick 				Scroll();
92052130Smckusick 			else
92152130Smckusick 				pmu.scrInfo.row++;
92252130Smckusick 		}
92352130Smckusick 		/*
92452130Smckusick 		 * 0xA1 to 0xFD are the printable characters added with 8-bit
92552130Smckusick 		 * support.
92652130Smckusick 		 */
92752130Smckusick 		if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD)
92852130Smckusick 			break;
92952130Smckusick 		bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR +
93052130Smckusick 			(pmu.scrInfo.row * 15 & 0x3ff) * ote +
93152130Smckusick 			pmu.scrInfo.col * colMult);
93252130Smckusick 		i = c - ' ';
93352130Smckusick 		/*
93452130Smckusick 		 * This is to skip the (32) 8-bit
93552130Smckusick 		 * control chars, as well as DEL
93652130Smckusick 		 * and 0xA0 which aren't printable
93752130Smckusick 		 */
93852130Smckusick 		if (c > '~')
93952130Smckusick 			i -= 34;
94052130Smckusick 		i *= 15;
94152130Smckusick 		fRow = (char *)((int)pmFont + i);
94252130Smckusick 
94352130Smckusick 		/* inline expansion for speed */
94452130Smckusick 		if (isMono) {
94552130Smckusick 			*bRow = *fRow++; bRow += ote;
94652130Smckusick 			*bRow = *fRow++; bRow += ote;
94752130Smckusick 			*bRow = *fRow++; bRow += ote;
94852130Smckusick 			*bRow = *fRow++; bRow += ote;
94952130Smckusick 			*bRow = *fRow++; bRow += ote;
95052130Smckusick 			*bRow = *fRow++; bRow += ote;
95152130Smckusick 			*bRow = *fRow++; bRow += ote;
95252130Smckusick 			*bRow = *fRow++; bRow += ote;
95352130Smckusick 			*bRow = *fRow++; bRow += ote;
95452130Smckusick 			*bRow = *fRow++; bRow += ote;
95552130Smckusick 			*bRow = *fRow++; bRow += ote;
95652130Smckusick 			*bRow = *fRow++; bRow += ote;
95752130Smckusick 			*bRow = *fRow++; bRow += ote;
95852130Smckusick 			*bRow = *fRow++; bRow += ote;
95952130Smckusick 			*bRow = *fRow++; bRow += ote;
96052130Smckusick 		} else {
96152130Smckusick 			register int j;
96252130Smckusick 			register unsigned int *pInt;
96352130Smckusick 
96452130Smckusick 			pInt = (unsigned int *)bRow;
96552130Smckusick 			for (j = 0; j < 15; j++) {
96652130Smckusick 				/*
96752130Smckusick 				 * fontmaskBits converts a nibble
96852130Smckusick 				 * (4 bytes) to a long word
96952130Smckusick 				 * containing 4 pixels corresponding
97052130Smckusick 				 * to each bit in the nibble.  Thus
97152130Smckusick 				 * we write two longwords for each
97252130Smckusick 				 * byte in font.
97352130Smckusick 				 *
97452130Smckusick 				 * Remember the font is 8 bits wide
97552130Smckusick 				 * and 15 bits high.
97652130Smckusick 				 *
97752130Smckusick 				 * We add 256 to the pointer to
97852130Smckusick 				 * point to the pixel on the
97952130Smckusick 				 * next scan line
98052130Smckusick 				 * directly below the current
98152130Smckusick 				 * pixel.
98252130Smckusick 				 */
98352130Smckusick 				pInt[0] = fontmaskBits[(*fRow) & 0xf];
98452130Smckusick 				pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf];
98552130Smckusick 				fRow++;
98652130Smckusick 				pInt += 256;
98752130Smckusick 			}
98852130Smckusick 		}
98952130Smckusick 		pmu.scrInfo.col++; /* increment column counter */
99052130Smckusick 	}
99152130Smckusick 	if (!GraphicsOpen)
99252130Smckusick 		PosCursor(pmu.scrInfo.col * 8, pmu.scrInfo.row * 15);
99352130Smckusick }
99452130Smckusick 
99552130Smckusick /*ARGSUSED*/
99652130Smckusick pmopen(dev, flag)
99752130Smckusick 	dev_t dev;
99852130Smckusick 	int flag;
99952130Smckusick {
100052130Smckusick 
100152130Smckusick 	if (!initialized)
100252130Smckusick 		return (ENXIO);
100352130Smckusick 	if (GraphicsOpen)
100452130Smckusick 		return (EBUSY);
100552130Smckusick 
100652130Smckusick 	GraphicsOpen = 1;
100752130Smckusick 	if (!isMono)
100852130Smckusick 		InitColorMap();
100952130Smckusick 	/*
101052130Smckusick 	 * Set up event queue for later
101152130Smckusick 	 */
101252130Smckusick 	pmu.scrInfo.qe.eSize = PM_MAXEVQ;
101352130Smckusick 	pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0;
101452130Smckusick 	pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
101552130Smckusick 	pmu.scrInfo.qe.tcNext = 0;
101652130Smckusick 	pmu.scrInfo.qe.timestamp_ms = TO_MS(time);
101752130Smckusick 	return (0);
101852130Smckusick }
101952130Smckusick 
102052130Smckusick /*ARGSUSED*/
102152130Smckusick pmclose(dev, flag)
102252130Smckusick 	dev_t dev;
102352130Smckusick 	int flag;
102452130Smckusick {
102552130Smckusick 
102652130Smckusick 	if (!GraphicsOpen)
102752130Smckusick 		return (EBADF);
102852130Smckusick 
102952130Smckusick 	GraphicsOpen = 0;
103052130Smckusick 	if (!isMono)
103152130Smckusick 		InitColorMap();
103252130Smckusick 	ScreenInit();
103352130Smckusick 	vmUserUnmap();
103452130Smckusick 	return (0);
103552130Smckusick }
103652130Smckusick 
103752130Smckusick /*ARGSUSED*/
103852130Smckusick pmioctl(dev, cmd, data, flag)
103952130Smckusick 	dev_t dev;
104052130Smckusick 	caddr_t data;
104152130Smckusick {
104252130Smckusick 	register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR;
104352130Smckusick 	extern int dcDivertXInput;
104452130Smckusick 
104552130Smckusick 	switch (cmd) {
104652130Smckusick 	case QIOCGINFO:
104752130Smckusick 	    {
104852130Smckusick 		caddr_t addr;
104952130Smckusick 		extern caddr_t vmUserMap();
105052130Smckusick 
105152130Smckusick 		/*
105252130Smckusick 		 * Map the all the data the user needs access to into
105352130Smckusick 		 * user space.
105452130Smckusick 		 */
105552130Smckusick 		addr = vmUserMap(sizeof(pmu), (unsigned)&pmu);
105652130Smckusick 		if (addr == (caddr_t)0)
105752130Smckusick 			goto mapError;
105852130Smckusick 		*(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo;
105952130Smckusick 		pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events;
106052130Smckusick 		pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs;
106152130Smckusick 		/*
106252130Smckusick 		 * Map the plane mask into the user's address space.
106352130Smckusick 		 */
106452130Smckusick 		addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR);
106552130Smckusick 		if (addr == (caddr_t)0)
106652130Smckusick 			goto mapError;
106752130Smckusick 		pmu.scrInfo.planemask = (char *)addr;
106852130Smckusick 		/*
106952130Smckusick 		 * Map the bitmap into the user's address space.
107052130Smckusick 		 */
107152130Smckusick 		addr = vmUserMap(isMono ? 256*1024 : 1024*1024,
107252130Smckusick 			(unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR);
107352130Smckusick 		if (addr == (caddr_t)0)
107452130Smckusick 			goto mapError;
107552130Smckusick 		pmu.scrInfo.bitmap = (char *)addr;
107652130Smckusick 		break;
107752130Smckusick 
107852130Smckusick 	mapError:
107952130Smckusick 		vmUserUnmap();
108052130Smckusick 		printf("Cannot map shared data structures\n");
108152130Smckusick 		return (EIO);
108252130Smckusick 	    }
108352130Smckusick 
108452130Smckusick 	case QIOCPMSTATE:
108552130Smckusick 		/*
108652130Smckusick 		 * Set mouse state.
108752130Smckusick 		 */
108852130Smckusick 		pmu.scrInfo.mouse = *(pmCursor *)data;
108952130Smckusick 		PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y);
109052130Smckusick 		break;
109152130Smckusick 
109252130Smckusick 	case QIOCINIT:
109352130Smckusick 		/*
109452130Smckusick 		 * Initialize the screen.
109552130Smckusick 		 */
109652130Smckusick 		ScreenInit();
109752130Smckusick 		break;
109852130Smckusick 
109952130Smckusick 	case QIOCKPCMD:
110052130Smckusick 	    {
110152130Smckusick 		pmKpCmd *kpCmdPtr;
110252130Smckusick 		unsigned char *cp;
110352130Smckusick 
110452130Smckusick 		kpCmdPtr = (pmKpCmd *)data;
110552130Smckusick 		if (kpCmdPtr->nbytes == 0)
110652130Smckusick 			kpCmdPtr->cmd |= 0x80;
110752130Smckusick 		if (!GraphicsOpen)
110852130Smckusick 			kpCmdPtr->cmd |= 1;
110952130Smckusick 		dcKBDPutc((int)kpCmdPtr->cmd);
111052130Smckusick 		cp = &kpCmdPtr->par[0];
111152130Smckusick 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
111252130Smckusick 			if (kpCmdPtr->nbytes == 1)
111352130Smckusick 				*cp |= 0x80;
111452130Smckusick 			dcKBDPutc((int)*cp);
111552130Smckusick 		}
111652130Smckusick 		break;
111752130Smckusick 	    }
111852130Smckusick 
111952130Smckusick 	case QIOCADDR:
112052130Smckusick 		*(PM_Info **)data = &pmu.scrInfo;
112152130Smckusick 		break;
112252130Smckusick 
112352130Smckusick 	case QIOWCURSOR:
112452130Smckusick 		LoadCursor((unsigned short *)data);
112552130Smckusick 		break;
112652130Smckusick 
112752130Smckusick 	case QIOWCURSORCOLOR:
112852130Smckusick 		CursorColor((unsigned int *)data);
112952130Smckusick 		break;
113052130Smckusick 
113152130Smckusick 	case QIOSETCMAP:
113252130Smckusick 		LoadColorMap((ColorMap *)data);
113352130Smckusick 		break;
113452130Smckusick 
113552130Smckusick 	case QIOKERNLOOP:
113652130Smckusick 		printf("pmioctl: QIOKERNLOOP\n"); /* XXX */
113752130Smckusick 		dcDivertXInput = 1;
113852130Smckusick 		break;
113952130Smckusick 
114052130Smckusick 	case QIOKERNUNLOOP:
114152130Smckusick 		printf("pmioctl: QIOKERNUNLOOP\n"); /* XXX */
114252130Smckusick 		dcDivertXInput = 0;
114352130Smckusick 		break;
114452130Smckusick 
114552130Smckusick 	case QIOVIDEOON:
114652130Smckusick 		if (!isMono)
114752130Smckusick 			RestoreCursorColor();
114852130Smckusick 		curReg |= PCC_ENPA;
114952130Smckusick 		curReg &= ~PCC_FOPB;
115052130Smckusick 		pcc->cmdr = curReg;
115152130Smckusick 		break;
115252130Smckusick 
115352130Smckusick 	case QIOVIDEOOFF:
115452130Smckusick 		if (!isMono)
115552130Smckusick 			VDACInit();
115652130Smckusick 		curReg |= PCC_FOPB;
115752130Smckusick 		curReg &= ~PCC_ENPA;
115852130Smckusick 		pcc->cmdr = curReg;
115952130Smckusick 		break;
116052130Smckusick 
116152130Smckusick 	default:
116252130Smckusick 		printf("pm0: Unknown command %x\n", cmd);
116352130Smckusick 		return (EINVAL);
116452130Smckusick 	}
116552130Smckusick 	return (0);
116652130Smckusick }
116752130Smckusick 
1168*52675Smckusick pmselect(dev, flag, p)
116952130Smckusick 	dev_t dev;
117052130Smckusick 	int flag;
1171*52675Smckusick 	struct proc *p;
117252130Smckusick {
117352130Smckusick 
117452130Smckusick 	switch (flag) {
117552130Smckusick 	case FREAD:
117652130Smckusick 		if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail)
117752130Smckusick 			return (1);
1178*52675Smckusick 		selrecord(p, &pm_selp);
117952130Smckusick 		break;
118052130Smckusick 	}
118152130Smckusick 
118252130Smckusick 	return (0);
118352130Smckusick }
118452130Smckusick #endif
1185