xref: /csrg-svn/sys/pmax/dev/mfb.c (revision 56815)
1*56815Sralph /*-
2*56815Sralph  * Copyright (c) 1992 The Regents of the University of California.
3*56815Sralph  * All rights reserved.
4*56815Sralph  *
5*56815Sralph  * This code is derived from software contributed to Berkeley by
6*56815Sralph  * Ralph Campbell and Rick Macklem.
7*56815Sralph  *
8*56815Sralph  * %sccs.include.redist.c%
9*56815Sralph  *
10*56815Sralph  *	@(#)mfb.c	7.1 (Berkeley) 11/15/92
11*56815Sralph  */
12*56815Sralph 
13*56815Sralph /*
14*56815Sralph  * Mach Operating System
15*56815Sralph  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
16*56815Sralph  * All Rights Reserved.
17*56815Sralph  *
18*56815Sralph  * Permission to use, copy, modify and distribute this software and its
19*56815Sralph  * documentation is hereby granted, provided that both the copyright
20*56815Sralph  * notice and this permission notice appear in all copies of the
21*56815Sralph  * software, derivative works or modified versions, and any portions
22*56815Sralph  * thereof, and that both notices appear in supporting documentation.
23*56815Sralph  *
24*56815Sralph  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
25*56815Sralph  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
26*56815Sralph  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
27*56815Sralph  *
28*56815Sralph  * Carnegie Mellon requests users of this software to return to
29*56815Sralph  *
30*56815Sralph  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
31*56815Sralph  *  School of Computer Science
32*56815Sralph  *  Carnegie Mellon University
33*56815Sralph  *  Pittsburgh PA 15213-3890
34*56815Sralph  *
35*56815Sralph  * any improvements or extensions that they make and grant Carnegie the
36*56815Sralph  * rights to redistribute these changes.
37*56815Sralph  */
38*56815Sralph /*
39*56815Sralph  *  devGraphics.c --
40*56815Sralph  *
41*56815Sralph  *     	This file contains machine-dependent routines for the graphics device.
42*56815Sralph  *
43*56815Sralph  *	Copyright (C) 1989 Digital Equipment Corporation.
44*56815Sralph  *	Permission to use, copy, modify, and distribute this software and
45*56815Sralph  *	its documentation for any purpose and without fee is hereby granted,
46*56815Sralph  *	provided that the above copyright notice appears in all copies.
47*56815Sralph  *	Digital Equipment Corporation makes no representations about the
48*56815Sralph  *	suitability of this software for any purpose.  It is provided "as is"
49*56815Sralph  *	without express or implied warranty.
50*56815Sralph  *
51*56815Sralph  * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
52*56815Sralph  *	v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
53*56815Sralph  */
54*56815Sralph 
55*56815Sralph #include <mfb.h>
56*56815Sralph #if NMFB > 0
57*56815Sralph #include <sys/param.h>
58*56815Sralph #include <sys/time.h>
59*56815Sralph #include <sys/kernel.h>
60*56815Sralph #include <sys/ioctl.h>
61*56815Sralph #include <sys/file.h>
62*56815Sralph #include <sys/errno.h>
63*56815Sralph #include <sys/proc.h>
64*56815Sralph #include <sys/mman.h>
65*56815Sralph 
66*56815Sralph #include <vm/vm.h>
67*56815Sralph 
68*56815Sralph #include <machine/machConst.h>
69*56815Sralph #include <machine/pmioctl.h>
70*56815Sralph 
71*56815Sralph #include <pmax/pmax/cons.h>
72*56815Sralph #include <pmax/pmax/pmaxtype.h>
73*56815Sralph 
74*56815Sralph #include <pmax/dev/device.h>
75*56815Sralph #include <pmax/dev/mfbreg.h>
76*56815Sralph #include <pmax/dev/fbreg.h>
77*56815Sralph 
78*56815Sralph #include <dc.h>
79*56815Sralph #include <dtop.h>
80*56815Sralph #include <scc.h>
81*56815Sralph 
82*56815Sralph /*
83*56815Sralph  * These need to be mapped into user space.
84*56815Sralph  */
85*56815Sralph struct fbuaccess mfbu;
86*56815Sralph struct pmax_fb mfbfb;
87*56815Sralph 
88*56815Sralph /*
89*56815Sralph  * Forward references.
90*56815Sralph  */
91*56815Sralph extern void fbScroll();
92*56815Sralph 
93*56815Sralph static void mfbScreenInit();
94*56815Sralph static void mfbLoadCursor();
95*56815Sralph static void mfbRestoreCursorColor();
96*56815Sralph static void mfbCursorColor();
97*56815Sralph void mfbPosCursor();
98*56815Sralph static void mfbInitColorMap();
99*56815Sralph static void mfbLoadColorMap();
100*56815Sralph static void mfbConfigMouse(), mfbDeconfigMouse();
101*56815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg();
102*56815Sralph static void bt431_write_reg(), bt431_init();
103*56815Sralph static u_char bt431_read_reg();
104*56815Sralph 
105*56815Sralph extern void fbKbdEvent(), fbMouseEvent(), fbMouseButtons();
106*56815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons();
107*56815Sralph #if NDC > 0
108*56815Sralph #include <machine/dc7085cons.h>
109*56815Sralph extern void dcPutc();
110*56815Sralph extern void (*dcDivertXInput)();
111*56815Sralph extern void (*dcMouseEvent)();
112*56815Sralph extern void (*dcMouseButtons)();
113*56815Sralph #endif
114*56815Sralph #if NSCC > 0
115*56815Sralph #include <pmax/dev/sccreg.h>
116*56815Sralph extern void sccPutc();
117*56815Sralph extern void (*sccDivertXInput)();
118*56815Sralph extern void (*sccMouseEvent)();
119*56815Sralph extern void (*sccMouseButtons)();
120*56815Sralph #endif
121*56815Sralph #if NDTOP > 0
122*56815Sralph #include <pmax/dev/dtopreg.h>
123*56815Sralph extern void dtopKBDPutc();
124*56815Sralph extern void (*dtopDivertXInput)();
125*56815Sralph extern void (*dtopMouseEvent)();
126*56815Sralph extern void (*dtopMouseButtons)();
127*56815Sralph #endif
128*56815Sralph extern int pmax_boardtype;
129*56815Sralph extern u_short defCursor[32];
130*56815Sralph extern struct consdev cn_tab;
131*56815Sralph 
132*56815Sralph int	mfbprobe();
133*56815Sralph struct	driver mfbdriver = {
134*56815Sralph 	"mfb", mfbprobe, 0, 0,
135*56815Sralph };
136*56815Sralph 
137*56815Sralph #define	MFB_OFFSET_VRAM		0x200000	/* from module's base */
138*56815Sralph #define MFB_OFFSET_BT431	0x180000	/* Bt431 registers */
139*56815Sralph #define MFB_OFFSET_BT455	0x100000	/* Bt455 registers */
140*56815Sralph #define MFB_OFFSET_IREQ		0x080000	/* Interrupt req. control */
141*56815Sralph #define MFB_OFFSET_ROM		0x0		/* Diagnostic ROM */
142*56815Sralph 
143*56815Sralph /*
144*56815Sralph  * Test to see if device is present.
145*56815Sralph  * Return true if found and initialized ok.
146*56815Sralph  */
147*56815Sralph /*ARGSUSED*/
148*56815Sralph mfbprobe(cp)
149*56815Sralph 	register struct pmax_ctlr *cp;
150*56815Sralph {
151*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
152*56815Sralph 
153*56815Sralph 	if (!fp->initialized && !mfbinit(cp->pmax_addr))
154*56815Sralph 		return (0);
155*56815Sralph 	printf("mfb0 (mono display)\n");
156*56815Sralph 	return (1);
157*56815Sralph }
158*56815Sralph 
159*56815Sralph /*ARGSUSED*/
160*56815Sralph mfbopen(dev, flag)
161*56815Sralph 	dev_t dev;
162*56815Sralph 	int flag;
163*56815Sralph {
164*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
165*56815Sralph 	int s;
166*56815Sralph 
167*56815Sralph 	if (!fp->initialized)
168*56815Sralph 		return (ENXIO);
169*56815Sralph 	if (fp->GraphicsOpen)
170*56815Sralph 		return (EBUSY);
171*56815Sralph 
172*56815Sralph 	fp->GraphicsOpen = 1;
173*56815Sralph 	mfbInitColorMap();
174*56815Sralph 	/*
175*56815Sralph 	 * Set up event queue for later
176*56815Sralph 	 */
177*56815Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
178*56815Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
179*56815Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
180*56815Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
181*56815Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
182*56815Sralph 	mfbConfigMouse();
183*56815Sralph 	return (0);
184*56815Sralph }
185*56815Sralph 
186*56815Sralph /*ARGSUSED*/
187*56815Sralph mfbclose(dev, flag)
188*56815Sralph 	dev_t dev;
189*56815Sralph 	int flag;
190*56815Sralph {
191*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
192*56815Sralph 	int s;
193*56815Sralph 
194*56815Sralph 	if (!fp->GraphicsOpen)
195*56815Sralph 		return (EBADF);
196*56815Sralph 
197*56815Sralph 	fp->GraphicsOpen = 0;
198*56815Sralph 	mfbInitColorMap();
199*56815Sralph 	mfbDeconfigMouse();
200*56815Sralph 	mfbScreenInit();
201*56815Sralph 	vmUserUnmap();
202*56815Sralph 	bzero((caddr_t)fp->fr_addr, 256 * 1024);
203*56815Sralph 	mfbPosCursor(fp->col * 8, fp->row * 15);
204*56815Sralph 	return (0);
205*56815Sralph }
206*56815Sralph 
207*56815Sralph /*ARGSUSED*/
208*56815Sralph mfbioctl(dev, cmd, data, flag)
209*56815Sralph 	dev_t dev;
210*56815Sralph 	caddr_t data;
211*56815Sralph {
212*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
213*56815Sralph 	int s;
214*56815Sralph 
215*56815Sralph 	switch (cmd) {
216*56815Sralph 	case QIOCGINFO:
217*56815Sralph 	    {
218*56815Sralph 		caddr_t addr;
219*56815Sralph 		extern caddr_t vmUserMap();
220*56815Sralph 
221*56815Sralph 		/*
222*56815Sralph 		 * Map the all the data the user needs access to into
223*56815Sralph 		 * user space.
224*56815Sralph 		 */
225*56815Sralph 		addr = vmUserMap(sizeof(struct fbuaccess), (unsigned)fp->fbu);
226*56815Sralph 		if (addr == (caddr_t)0)
227*56815Sralph 			goto mapError;
228*56815Sralph 		*(PM_Info **)data = &((struct fbuaccess *)addr)->scrInfo;
229*56815Sralph 		fp->fbu->scrInfo.qe.events = ((struct fbuaccess *)addr)->events;
230*56815Sralph 		fp->fbu->scrInfo.qe.tcs = ((struct fbuaccess *)addr)->tcs;
231*56815Sralph 		fp->fbu->scrInfo.planemask = (char *)0;
232*56815Sralph 		/*
233*56815Sralph 		 * Map the frame buffer into the user's address space.
234*56815Sralph 		 */
235*56815Sralph 		addr = vmUserMap(256 * 1024,
236*56815Sralph 			(unsigned)(fp->fr_addr + MFB_OFFSET_VRAM));
237*56815Sralph 		if (addr == (caddr_t)0)
238*56815Sralph 			goto mapError;
239*56815Sralph 		fp->fbu->scrInfo.bitmap = (char *)addr;
240*56815Sralph 		break;
241*56815Sralph 
242*56815Sralph 	mapError:
243*56815Sralph 		vmUserUnmap();
244*56815Sralph 		printf("Cannot map shared data structures\n");
245*56815Sralph 		return (EIO);
246*56815Sralph 	    }
247*56815Sralph 
248*56815Sralph 	case QIOCPMSTATE:
249*56815Sralph 		/*
250*56815Sralph 		 * Set mouse state.
251*56815Sralph 		 */
252*56815Sralph 		fp->fbu->scrInfo.mouse = *(pmCursor *)data;
253*56815Sralph 		mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
254*56815Sralph 		break;
255*56815Sralph 
256*56815Sralph 	case QIOCINIT:
257*56815Sralph 		/*
258*56815Sralph 		 * Initialize the screen.
259*56815Sralph 		 */
260*56815Sralph 		mfbScreenInit();
261*56815Sralph 		break;
262*56815Sralph 
263*56815Sralph 	case QIOCKPCMD:
264*56815Sralph 	    {
265*56815Sralph 		pmKpCmd *kpCmdPtr;
266*56815Sralph 		unsigned char *cp;
267*56815Sralph 
268*56815Sralph 		kpCmdPtr = (pmKpCmd *)data;
269*56815Sralph 		if (kpCmdPtr->nbytes == 0)
270*56815Sralph 			kpCmdPtr->cmd |= 0x80;
271*56815Sralph 		if (!fp->GraphicsOpen)
272*56815Sralph 			kpCmdPtr->cmd |= 1;
273*56815Sralph 		(*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
274*56815Sralph 		cp = &kpCmdPtr->par[0];
275*56815Sralph 		for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
276*56815Sralph 			if (kpCmdPtr->nbytes == 1)
277*56815Sralph 				*cp |= 0x80;
278*56815Sralph 			(*fp->KBDPutc)(fp->kbddev, (int)*cp);
279*56815Sralph 		}
280*56815Sralph 	    }
281*56815Sralph 	    break;
282*56815Sralph 
283*56815Sralph 	case QIOCADDR:
284*56815Sralph 		*(PM_Info **)data = &fp->fbu->scrInfo;
285*56815Sralph 		break;
286*56815Sralph 
287*56815Sralph 	case QIOWCURSOR:
288*56815Sralph 		mfbLoadCursor((unsigned short *)data);
289*56815Sralph 		break;
290*56815Sralph 
291*56815Sralph 	case QIOWCURSORCOLOR:
292*56815Sralph 		mfbCursorColor((unsigned int *)data);
293*56815Sralph 		break;
294*56815Sralph 
295*56815Sralph 	case QIOSETCMAP:
296*56815Sralph 		mfbLoadColorMap((ColorMap *)data);
297*56815Sralph 		break;
298*56815Sralph 
299*56815Sralph 	case QIOKERNLOOP:
300*56815Sralph 		mfbConfigMouse();
301*56815Sralph 		break;
302*56815Sralph 
303*56815Sralph 	case QIOKERNUNLOOP:
304*56815Sralph 		mfbDeconfigMouse();
305*56815Sralph 		break;
306*56815Sralph 
307*56815Sralph 	case QIOVIDEOON:
308*56815Sralph 		mfbRestoreCursorColor();
309*56815Sralph 		bt455_video_on();
310*56815Sralph 		break;
311*56815Sralph 
312*56815Sralph 	case QIOVIDEOOFF:
313*56815Sralph 		bt455_video_off();
314*56815Sralph 		break;
315*56815Sralph 
316*56815Sralph 	default:
317*56815Sralph 		printf("mfb0: Unknown ioctl command %x\n", cmd);
318*56815Sralph 		return (EINVAL);
319*56815Sralph 	}
320*56815Sralph 	return (0);
321*56815Sralph }
322*56815Sralph 
323*56815Sralph mfbselect(dev, flag, p)
324*56815Sralph 	dev_t dev;
325*56815Sralph 	int flag;
326*56815Sralph 	struct proc *p;
327*56815Sralph {
328*56815Sralph 	struct pmax_fb *fp = &mfbfb;
329*56815Sralph 
330*56815Sralph 	switch (flag) {
331*56815Sralph 	case FREAD:
332*56815Sralph 		if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
333*56815Sralph 			return (1);
334*56815Sralph 		selrecord(p, &fp->selp);
335*56815Sralph 		break;
336*56815Sralph 	}
337*56815Sralph 
338*56815Sralph 	return (0);
339*56815Sralph }
340*56815Sralph 
341*56815Sralph static u_char	cursor_RGB[6];	/* cursor color 2 & 3 */
342*56815Sralph 
343*56815Sralph /*
344*56815Sralph  * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit
345*56815Sralph  * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding
346*56815Sralph  * registers for these two chips live in adjacent bytes of the shorts that
347*56815Sralph  * are defined in bt431_regmap_t.
348*56815Sralph  */
349*56815Sralph static void
350*56815Sralph mfbLoadCursor(cursor)
351*56815Sralph 	u_short *cursor;
352*56815Sralph {
353*56815Sralph 	register int i, j, k, pos;
354*56815Sralph 	register u_short ap, bp, out;
355*56815Sralph 	register bt431_regmap_t *regs;
356*56815Sralph 
357*56815Sralph 	regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431);
358*56815Sralph 	/*
359*56815Sralph 	 * Fill in the cursor sprite using the A and B planes, as provided
360*56815Sralph 	 * for the pmax.
361*56815Sralph 	 * XXX This will have to change when the X server knows that this
362*56815Sralph 	 * is not a pmax display.
363*56815Sralph 	 */
364*56815Sralph 	pos = 0;
365*56815Sralph 	bt431_select_reg(regs, BT431_REG_CRAM_BASE);
366*56815Sralph 	for (k = 0; k < 16; k++) {
367*56815Sralph 		ap = *cursor;
368*56815Sralph 		bp = *(cursor + 16);
369*56815Sralph 		j = 0;
370*56815Sralph 		while (j < 2) {
371*56815Sralph 			out = 0;
372*56815Sralph 			for (i = 0; i < 8; i++) {
373*56815Sralph 				out = (out << 1) | ((ap & 0x1) << 8) |
374*56815Sralph 					(bp & 0x1);
375*56815Sralph 				ap >>= 1;
376*56815Sralph 				bp >>= 1;
377*56815Sralph 			}
378*56815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, out);
379*56815Sralph 			pos++;
380*56815Sralph 			j++;
381*56815Sralph 		}
382*56815Sralph 		while (j < 8) {
383*56815Sralph 			BT431_WRITE_CMAP_AUTOI(regs, 0);
384*56815Sralph 			pos++;
385*56815Sralph 			j++;
386*56815Sralph 		}
387*56815Sralph 		cursor++;
388*56815Sralph 	}
389*56815Sralph 	while (pos < 512) {
390*56815Sralph 		BT431_WRITE_CMAP_AUTOI(regs, 0);
391*56815Sralph 		pos++;
392*56815Sralph 	}
393*56815Sralph }
394*56815Sralph 
395*56815Sralph /*
396*56815Sralph  * Initialization
397*56815Sralph  */
398*56815Sralph int
399*56815Sralph mfbinit(cp)
400*56815Sralph 	char *cp;
401*56815Sralph {
402*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
403*56815Sralph 
404*56815Sralph 	/* check for no frame buffer */
405*56815Sralph 	if (badaddr(cp, 4))
406*56815Sralph 		return (0);
407*56815Sralph 
408*56815Sralph 	fp->isMono = 1;
409*56815Sralph 	fp->fr_addr = (char *)cp;
410*56815Sralph 	fp->fbu = &mfbu;
411*56815Sralph 	fp->posCursor = mfbPosCursor;
412*56815Sralph 	switch (pmax_boardtype) {
413*56815Sralph #if NDC > 0
414*56815Sralph 	case DS_3MAX:
415*56815Sralph 		fp->KBDPutc = dcPutc;
416*56815Sralph 		fp->kbddev = makedev(DCDEV, DCKBD_PORT);
417*56815Sralph 		break;
418*56815Sralph #endif
419*56815Sralph #if NSCC > 0
420*56815Sralph 	case DS_3MIN:
421*56815Sralph 		fp->KBDPutc = sccPutc;
422*56815Sralph 		fp->kbddev = makedev(SCCDEV, SCCKBD_PORT);
423*56815Sralph 		break;
424*56815Sralph #endif
425*56815Sralph #if NDTOP > 0
426*56815Sralph 	case DS_MAXINE:
427*56815Sralph 		fp->KBDPutc = dtopKBDPutc;
428*56815Sralph 		fp->kbddev = makedev(DTOPDEV, DTOPKBD_PORT);
429*56815Sralph 		break;
430*56815Sralph #endif
431*56815Sralph 	default:
432*56815Sralph 		printf("Can't configure keyboard/mouse\n");
433*56815Sralph 		return (0);
434*56815Sralph 	};
435*56815Sralph 
436*56815Sralph 	/*
437*56815Sralph 	 * Initialize the screen.
438*56815Sralph 	 */
439*56815Sralph 	bt431_init(fp->fr_addr + MFB_OFFSET_BT431);
440*56815Sralph 
441*56815Sralph 	/*
442*56815Sralph 	 * Initialize screen info.
443*56815Sralph 	 */
444*56815Sralph 	fp->fbu->scrInfo.max_row = 67;
445*56815Sralph 	fp->fbu->scrInfo.max_col = 80;
446*56815Sralph 	fp->fbu->scrInfo.max_x = 1280;
447*56815Sralph 	fp->fbu->scrInfo.max_y = 1024;
448*56815Sralph 	fp->fbu->scrInfo.max_cur_x = 1279;
449*56815Sralph 	fp->fbu->scrInfo.max_cur_y = 1023;
450*56815Sralph 	fp->fbu->scrInfo.version = 11;
451*56815Sralph 	fp->fbu->scrInfo.mthreshold = 4;
452*56815Sralph 	fp->fbu->scrInfo.mscale = 2;
453*56815Sralph 	fp->fbu->scrInfo.min_cur_x = 0;
454*56815Sralph 	fp->fbu->scrInfo.min_cur_y = 0;
455*56815Sralph 	fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
456*56815Sralph 	fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
457*56815Sralph 	fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
458*56815Sralph 	fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
459*56815Sralph 	fp->fbu->scrInfo.qe.tcNext = 0;
460*56815Sralph 
461*56815Sralph 	/*
462*56815Sralph 	 * Initialize the color map, the screen, and the mouse.
463*56815Sralph 	 */
464*56815Sralph 	mfbInitColorMap();
465*56815Sralph 	mfbScreenInit();
466*56815Sralph 	fbScroll(fp);
467*56815Sralph 
468*56815Sralph 	fp->initialized = 1;
469*56815Sralph 	if (cn_tab.cn_fb == (struct pmax_fb *)0)
470*56815Sralph 		cn_tab.cn_fb = fp;
471*56815Sralph 	return (1);
472*56815Sralph }
473*56815Sralph 
474*56815Sralph /*
475*56815Sralph  * ----------------------------------------------------------------------------
476*56815Sralph  *
477*56815Sralph  * mfbScreenInit --
478*56815Sralph  *
479*56815Sralph  *	Initialize the screen.
480*56815Sralph  *
481*56815Sralph  * Results:
482*56815Sralph  *	None.
483*56815Sralph  *
484*56815Sralph  * Side effects:
485*56815Sralph  *	The screen is initialized.
486*56815Sralph  *
487*56815Sralph  * ----------------------------------------------------------------------------
488*56815Sralph  */
489*56815Sralph static void
490*56815Sralph mfbScreenInit()
491*56815Sralph {
492*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
493*56815Sralph 
494*56815Sralph 	/*
495*56815Sralph 	 * Home the cursor.
496*56815Sralph 	 * We want an LSI terminal emulation.  We want the graphics
497*56815Sralph 	 * terminal to scroll from the bottom. So start at the bottom.
498*56815Sralph 	 */
499*56815Sralph 	fp->row = 66;
500*56815Sralph 	fp->col = 0;
501*56815Sralph 
502*56815Sralph 	/*
503*56815Sralph 	 * Load the cursor with the default values
504*56815Sralph 	 *
505*56815Sralph 	 */
506*56815Sralph 	mfbLoadCursor(defCursor);
507*56815Sralph }
508*56815Sralph 
509*56815Sralph /*
510*56815Sralph  * ----------------------------------------------------------------------------
511*56815Sralph  *
512*56815Sralph  * RestoreCursorColor --
513*56815Sralph  *
514*56815Sralph  *	Routine to restore the color of the cursor.
515*56815Sralph  *
516*56815Sralph  * Results:
517*56815Sralph  *	None.
518*56815Sralph  *
519*56815Sralph  * Side effects:
520*56815Sralph  *	None.
521*56815Sralph  *
522*56815Sralph  * ----------------------------------------------------------------------------
523*56815Sralph  */
524*56815Sralph static void
525*56815Sralph mfbRestoreCursorColor()
526*56815Sralph {
527*56815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
528*56815Sralph 	ColorMap cm;
529*56815Sralph 	register int i;
530*56815Sralph 
531*56815Sralph 	cm.index = 8;
532*56815Sralph 	cm.Entry.red = cursor_RGB[0] << 8;
533*56815Sralph 	cm.Entry.green = cursor_RGB[1] << 8;
534*56815Sralph 	cm.Entry.blue = cursor_RGB[2] << 8;
535*56815Sralph 	mfbLoadColorMap(&cm);
536*56815Sralph 	cm.index = 9;
537*56815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
538*56815Sralph 	mfbLoadColorMap(&cm);
539*56815Sralph 
540*56815Sralph 	regs->addr_ovly = cursor_RGB[3] >> 4;
541*56815Sralph 	MachEmptyWriteBuffer();
542*56815Sralph 	regs->addr_ovly = cursor_RGB[4] >> 4;
543*56815Sralph 	MachEmptyWriteBuffer();
544*56815Sralph 	regs->addr_ovly = cursor_RGB[5] >> 4;
545*56815Sralph 	MachEmptyWriteBuffer();
546*56815Sralph }
547*56815Sralph 
548*56815Sralph /*
549*56815Sralph  * ----------------------------------------------------------------------------
550*56815Sralph  *
551*56815Sralph  * CursorColor --
552*56815Sralph  *
553*56815Sralph  *	Set the color of the cursor.
554*56815Sralph  *
555*56815Sralph  * Results:
556*56815Sralph  *	None.
557*56815Sralph  *
558*56815Sralph  * Side effects:
559*56815Sralph  *	None.
560*56815Sralph  *
561*56815Sralph  * ----------------------------------------------------------------------------
562*56815Sralph  */
563*56815Sralph static void
564*56815Sralph mfbCursorColor(color)
565*56815Sralph 	unsigned int color[];
566*56815Sralph {
567*56815Sralph 	register int i, j;
568*56815Sralph 
569*56815Sralph 	for (i = 0; i < 6; i++)
570*56815Sralph 		cursor_RGB[i] = (u_char)(color[i] >> 8);
571*56815Sralph 
572*56815Sralph 	mfbRestoreCursorColor();
573*56815Sralph }
574*56815Sralph 
575*56815Sralph /*
576*56815Sralph  *----------------------------------------------------------------------
577*56815Sralph  *
578*56815Sralph  * PosCursor --
579*56815Sralph  *
580*56815Sralph  *	Postion the cursor.
581*56815Sralph  *
582*56815Sralph  * Results:
583*56815Sralph  *	None.
584*56815Sralph  *
585*56815Sralph  * Side effects:
586*56815Sralph  *	None.
587*56815Sralph  *
588*56815Sralph  *----------------------------------------------------------------------
589*56815Sralph  */
590*56815Sralph void
591*56815Sralph mfbPosCursor(x, y)
592*56815Sralph 	register int x, y;
593*56815Sralph {
594*56815Sralph 	bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT431);
595*56815Sralph 	register struct pmax_fb *fp = &mfbfb;
596*56815Sralph 
597*56815Sralph 	if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
598*56815Sralph 		y = fp->fbu->scrInfo.max_cur_y;
599*56815Sralph 	if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
600*56815Sralph 		x = fp->fbu->scrInfo.max_cur_x;
601*56815Sralph 	fp->fbu->scrInfo.cursor.x = x;		/* keep track of real cursor */
602*56815Sralph 	fp->fbu->scrInfo.cursor.y = y;		/* position, indep. of mouse */
603*56815Sralph 
604*56815Sralph #define lo(v)	((v)&0xff)
605*56815Sralph #define hi(v)	(((v)&0xf00)>>8)
606*56815Sralph 
607*56815Sralph 	/*
608*56815Sralph 	 * Cx = x + D + H - P
609*56815Sralph 	 *  P = 37 if 1:1, 52 if 4:1, 57 if 5:1
610*56815Sralph 	 *  D = pixel skew between outdata and external data
611*56815Sralph 	 *  H = pixels between HSYNCH falling and active video
612*56815Sralph 	 *
613*56815Sralph 	 * Cy = y + V - 32
614*56815Sralph 	 *  V = scanlines between HSYNCH falling, two or more
615*56815Sralph 	 *	clocks after VSYNCH falling, and active video
616*56815Sralph 	 */
617*56815Sralph 
618*56815Sralph 	bt431_write_reg(regs, lo(x + 360));
619*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(x + 360));
620*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, lo(y + 36));
621*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, hi(y + 36));
622*56815Sralph }
623*56815Sralph 
624*56815Sralph /*
625*56815Sralph  * ----------------------------------------------------------------------------
626*56815Sralph  *
627*56815Sralph  * InitColorMap --
628*56815Sralph  *
629*56815Sralph  *	Initialize the color map.
630*56815Sralph  *
631*56815Sralph  * Results:
632*56815Sralph  *	None.
633*56815Sralph  *
634*56815Sralph  * Side effects:
635*56815Sralph  *	The colormap is initialized appropriately.
636*56815Sralph  *
637*56815Sralph  * ----------------------------------------------------------------------------
638*56815Sralph  */
639*56815Sralph static void
640*56815Sralph mfbInitColorMap()
641*56815Sralph {
642*56815Sralph 	ColorMap cm;
643*56815Sralph 	register int i;
644*56815Sralph 
645*56815Sralph 	cm.index = 0;
646*56815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
647*56815Sralph 	mfbLoadColorMap(&cm);
648*56815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
649*56815Sralph 	for (i = 1; i < 16; i++) {
650*56815Sralph 		cm.index = i;
651*56815Sralph 		mfbLoadColorMap(&cm);
652*56815Sralph 	}
653*56815Sralph 
654*56815Sralph 	for (i = 0; i < 3; i++) {
655*56815Sralph 		cursor_RGB[i] = 0x00;
656*56815Sralph 		cursor_RGB[i + 3] = 0xff;
657*56815Sralph 	}
658*56815Sralph 	mfbRestoreCursorColor();
659*56815Sralph }
660*56815Sralph 
661*56815Sralph /*
662*56815Sralph  * ----------------------------------------------------------------------------
663*56815Sralph  *
664*56815Sralph  * LoadColorMap --
665*56815Sralph  *
666*56815Sralph  *	Load the color map.
667*56815Sralph  *
668*56815Sralph  * Results:
669*56815Sralph  *	None.
670*56815Sralph  *
671*56815Sralph  * Side effects:
672*56815Sralph  *	The color map is loaded.
673*56815Sralph  *
674*56815Sralph  * ----------------------------------------------------------------------------
675*56815Sralph  */
676*56815Sralph static void
677*56815Sralph mfbLoadColorMap(ptr)
678*56815Sralph 	ColorMap *ptr;
679*56815Sralph {
680*56815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
681*56815Sralph 
682*56815Sralph 	if (ptr->index > 15)
683*56815Sralph 		return;
684*56815Sralph 
685*56815Sralph 	BT455_SELECT_ENTRY(regs, ptr->index);
686*56815Sralph 	regs->addr_cmap_data = ptr->Entry.red >> 12;
687*56815Sralph 	MachEmptyWriteBuffer();
688*56815Sralph 	regs->addr_cmap_data = ptr->Entry.green >> 12;
689*56815Sralph 	MachEmptyWriteBuffer();
690*56815Sralph 	regs->addr_cmap_data = ptr->Entry.blue >> 12;
691*56815Sralph 	MachEmptyWriteBuffer();
692*56815Sralph }
693*56815Sralph 
694*56815Sralph /*
695*56815Sralph  * Video on/off state.
696*56815Sralph  */
697*56815Sralph static struct vstate {
698*56815Sralph 	u_char	color0[6];	/* saved color map entry zero */
699*56815Sralph 	u_char	off;		/* TRUE if display is off */
700*56815Sralph } vstate;
701*56815Sralph 
702*56815Sralph /*
703*56815Sralph  * ----------------------------------------------------------------------------
704*56815Sralph  *
705*56815Sralph  * bt455_video_on
706*56815Sralph  *
707*56815Sralph  *	Enable the video display.
708*56815Sralph  *
709*56815Sralph  * Results:
710*56815Sralph  *	None.
711*56815Sralph  *
712*56815Sralph  * Side effects:
713*56815Sralph  *	The display is enabled.
714*56815Sralph  *
715*56815Sralph  * ----------------------------------------------------------------------------
716*56815Sralph  */
717*56815Sralph static void
718*56815Sralph bt455_video_on()
719*56815Sralph {
720*56815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
721*56815Sralph 
722*56815Sralph 	if (!vstate.off)
723*56815Sralph 		return;
724*56815Sralph 
725*56815Sralph 	/* restore old color map entry zero */
726*56815Sralph 	BT455_SELECT_ENTRY(regs, 0);
727*56815Sralph 	regs->addr_cmap_data = vstate.color0[0];
728*56815Sralph 	MachEmptyWriteBuffer();
729*56815Sralph 	regs->addr_cmap_data = vstate.color0[1];
730*56815Sralph 	MachEmptyWriteBuffer();
731*56815Sralph 	regs->addr_cmap_data = vstate.color0[2];
732*56815Sralph 	MachEmptyWriteBuffer();
733*56815Sralph 	regs->addr_cmap_data = vstate.color0[3];
734*56815Sralph 	MachEmptyWriteBuffer();
735*56815Sralph 	regs->addr_cmap_data = vstate.color0[4];
736*56815Sralph 	MachEmptyWriteBuffer();
737*56815Sralph 	regs->addr_cmap_data = vstate.color0[5];
738*56815Sralph 	MachEmptyWriteBuffer();
739*56815Sralph 
740*56815Sralph 	vstate.off = 0;
741*56815Sralph }
742*56815Sralph 
743*56815Sralph /*
744*56815Sralph  * ----------------------------------------------------------------------------
745*56815Sralph  *
746*56815Sralph  * bt455_video_off
747*56815Sralph  *
748*56815Sralph  *	Disable the video display.
749*56815Sralph  *
750*56815Sralph  * Results:
751*56815Sralph  *	None.
752*56815Sralph  *
753*56815Sralph  * Side effects:
754*56815Sralph  *	The display is disabled.
755*56815Sralph  *
756*56815Sralph  * ----------------------------------------------------------------------------
757*56815Sralph  */
758*56815Sralph static void
759*56815Sralph bt455_video_off()
760*56815Sralph {
761*56815Sralph 	bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_addr + MFB_OFFSET_BT455);
762*56815Sralph 	ColorMap cm;
763*56815Sralph 
764*56815Sralph 	if (vstate.off)
765*56815Sralph 		return;
766*56815Sralph 
767*56815Sralph 	/* save old color map entry zero */
768*56815Sralph 	BT455_SELECT_ENTRY(regs, 0);
769*56815Sralph 	vstate.color0[0] = regs->addr_cmap_data;
770*56815Sralph 	vstate.color0[1] = regs->addr_cmap_data;
771*56815Sralph 	vstate.color0[2] = regs->addr_cmap_data;
772*56815Sralph 	vstate.color0[3] = regs->addr_cmap_data;
773*56815Sralph 	vstate.color0[4] = regs->addr_cmap_data;
774*56815Sralph 	vstate.color0[5] = regs->addr_cmap_data;
775*56815Sralph 
776*56815Sralph 	/* set color map entry zero to zero */
777*56815Sralph 	cm.index = 0;
778*56815Sralph 	cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
779*56815Sralph 	mfbLoadColorMap(&cm);
780*56815Sralph 	cm.index = 1;
781*56815Sralph 	mfbLoadColorMap(&cm);
782*56815Sralph 
783*56815Sralph 	vstate.off = 1;
784*56815Sralph }
785*56815Sralph 
786*56815Sralph /*
787*56815Sralph  * mfb keyboard and mouse input. Just punt to the generic ones in fb.c
788*56815Sralph  */
789*56815Sralph void
790*56815Sralph mfbKbdEvent(ch)
791*56815Sralph 	int ch;
792*56815Sralph {
793*56815Sralph 	fbKbdEvent(ch, &mfbfb);
794*56815Sralph }
795*56815Sralph 
796*56815Sralph void
797*56815Sralph mfbMouseEvent(newRepPtr)
798*56815Sralph 	MouseReport *newRepPtr;
799*56815Sralph {
800*56815Sralph 	fbMouseEvent(newRepPtr, &mfbfb);
801*56815Sralph }
802*56815Sralph 
803*56815Sralph void
804*56815Sralph mfbMouseButtons(newRepPtr)
805*56815Sralph 	MouseReport *newRepPtr;
806*56815Sralph {
807*56815Sralph 	fbMouseButtons(newRepPtr, &mfbfb);
808*56815Sralph }
809*56815Sralph 
810*56815Sralph /*
811*56815Sralph  * Configure the mouse and keyboard based on machine type
812*56815Sralph  */
813*56815Sralph static void
814*56815Sralph mfbConfigMouse()
815*56815Sralph {
816*56815Sralph 	int s;
817*56815Sralph 
818*56815Sralph 	s = spltty();
819*56815Sralph 	switch (pmax_boardtype) {
820*56815Sralph #if NDC > 0
821*56815Sralph 	case DS_3MAX:
822*56815Sralph 		dcDivertXInput = mfbKbdEvent;
823*56815Sralph 		dcMouseEvent = mfbMouseEvent;
824*56815Sralph 		dcMouseButtons = mfbMouseButtons;
825*56815Sralph 		break;
826*56815Sralph #endif
827*56815Sralph #if NSCC > 1
828*56815Sralph 	case DS_3MIN:
829*56815Sralph 		sccDivertXInput = mfbKbdEvent;
830*56815Sralph 		sccMouseEvent = mfbMouseEvent;
831*56815Sralph 		sccMouseButtons = mfbMouseButtons;
832*56815Sralph 		break;
833*56815Sralph #endif
834*56815Sralph #if NDTOP > 0
835*56815Sralph 	case DS_MAXINE:
836*56815Sralph 		dtopDivertXInput = mfbKbdEvent;
837*56815Sralph 		dtopMouseEvent = mfbMouseEvent;
838*56815Sralph 		dtopMouseButtons = mfbMouseButtons;
839*56815Sralph 		break;
840*56815Sralph #endif
841*56815Sralph 	default:
842*56815Sralph 		printf("Can't configure mouse/keyboard\n");
843*56815Sralph 	};
844*56815Sralph 	splx(s);
845*56815Sralph }
846*56815Sralph 
847*56815Sralph /*
848*56815Sralph  * and deconfigure them
849*56815Sralph  */
850*56815Sralph static void
851*56815Sralph mfbDeconfigMouse()
852*56815Sralph {
853*56815Sralph 	int s;
854*56815Sralph 
855*56815Sralph 	s = spltty();
856*56815Sralph 	switch (pmax_boardtype) {
857*56815Sralph #if NDC > 0
858*56815Sralph 	case DS_3MAX:
859*56815Sralph 		dcDivertXInput = (void (*)())0;
860*56815Sralph 		dcMouseEvent = (void (*)())0;
861*56815Sralph 		dcMouseButtons = (void (*)())0;
862*56815Sralph 		break;
863*56815Sralph #endif
864*56815Sralph #if NSCC > 1
865*56815Sralph 	case DS_3MIN:
866*56815Sralph 		sccDivertXInput = (void (*)())0;
867*56815Sralph 		sccMouseEvent = (void (*)())0;
868*56815Sralph 		sccMouseButtons = (void (*)())0;
869*56815Sralph 		break;
870*56815Sralph #endif
871*56815Sralph #if NDTOP > 0
872*56815Sralph 	case DS_MAXINE:
873*56815Sralph 		dtopDivertXInput = (void (*)())0;
874*56815Sralph 		dtopMouseEvent = (void (*)())0;
875*56815Sralph 		dtopMouseButtons = (void (*)())0;
876*56815Sralph 		break;
877*56815Sralph #endif
878*56815Sralph 	default:
879*56815Sralph 		printf("Can't deconfigure mouse/keyboard\n");
880*56815Sralph 	};
881*56815Sralph }
882*56815Sralph 
883*56815Sralph /*
884*56815Sralph  * Generic register access
885*56815Sralph  */
886*56815Sralph static void
887*56815Sralph bt431_select_reg(regs, regno)
888*56815Sralph 	bt431_regmap_t *regs;
889*56815Sralph {
890*56815Sralph 	regs->addr_lo = SET_VALUE(regno & 0xff);
891*56815Sralph 	regs->addr_hi = SET_VALUE((regno >> 8) & 0xff);
892*56815Sralph 	MachEmptyWriteBuffer();
893*56815Sralph }
894*56815Sralph 
895*56815Sralph static void
896*56815Sralph bt431_write_reg(regs, regno, val)
897*56815Sralph 	bt431_regmap_t *regs;
898*56815Sralph {
899*56815Sralph 	bt431_select_reg(regs, regno);
900*56815Sralph 	regs->addr_reg = SET_VALUE(val);
901*56815Sralph 	MachEmptyWriteBuffer();
902*56815Sralph }
903*56815Sralph 
904*56815Sralph static u_char
905*56815Sralph bt431_read_reg(regs, regno)
906*56815Sralph 	bt431_regmap_t *regs;
907*56815Sralph {
908*56815Sralph 	bt431_select_reg(regs, regno);
909*56815Sralph 	return (GET_VALUE(regs->addr_reg));
910*56815Sralph }
911*56815Sralph 
912*56815Sralph static void
913*56815Sralph bt431_init(regs)
914*56815Sralph 	bt431_regmap_t *regs;
915*56815Sralph {
916*56815Sralph 	register int i;
917*56815Sralph 
918*56815Sralph 	/* use 4:1 input mux */
919*56815Sralph 	bt431_write_reg(regs, BT431_REG_CMD,
920*56815Sralph 			 BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS|
921*56815Sralph 			 BT431_CMD_4_1_MUX|BT431_CMD_THICK_1);
922*56815Sralph 
923*56815Sralph 	/* home cursor */
924*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
925*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
926*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
927*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
928*56815Sralph 
929*56815Sralph 	/* no crosshair window */
930*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
931*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
932*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
933*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
934*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
935*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
936*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
937*56815Sralph 	BT431_WRITE_REG_AUTOI(regs, 0x00);
938*56815Sralph }
939*56815Sralph #endif /* NMFB */
940