156815Sralph /*-
263206Sbostic * Copyright (c) 1992, 1993
363206Sbostic * The Regents of the University of California. All rights reserved.
456815Sralph *
556815Sralph * This code is derived from software contributed to Berkeley by
656815Sralph * Ralph Campbell and Rick Macklem.
756815Sralph *
856815Sralph * %sccs.include.redist.c%
956815Sralph *
10*69799Sralph * @(#)mfb.c 8.2 (Berkeley) 06/02/95
1156815Sralph */
1256815Sralph
1356815Sralph /*
1456815Sralph * Mach Operating System
1556815Sralph * Copyright (c) 1991,1990,1989 Carnegie Mellon University
1656815Sralph * All Rights Reserved.
1756815Sralph *
1856815Sralph * Permission to use, copy, modify and distribute this software and its
1956815Sralph * documentation is hereby granted, provided that both the copyright
2056815Sralph * notice and this permission notice appear in all copies of the
2156815Sralph * software, derivative works or modified versions, and any portions
2256815Sralph * thereof, and that both notices appear in supporting documentation.
2356815Sralph *
2456815Sralph * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
2556815Sralph * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
2656815Sralph * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
2756815Sralph *
2856815Sralph * Carnegie Mellon requests users of this software to return to
2956815Sralph *
3056815Sralph * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
3156815Sralph * School of Computer Science
3256815Sralph * Carnegie Mellon University
3356815Sralph * Pittsburgh PA 15213-3890
3456815Sralph *
3556815Sralph * any improvements or extensions that they make and grant Carnegie the
3656815Sralph * rights to redistribute these changes.
3756815Sralph */
3856815Sralph /*
3956815Sralph * devGraphics.c --
4056815Sralph *
4156815Sralph * This file contains machine-dependent routines for the graphics device.
4256815Sralph *
4356815Sralph * Copyright (C) 1989 Digital Equipment Corporation.
4456815Sralph * Permission to use, copy, modify, and distribute this software and
4556815Sralph * its documentation for any purpose and without fee is hereby granted,
4656815Sralph * provided that the above copyright notice appears in all copies.
4756815Sralph * Digital Equipment Corporation makes no representations about the
4856815Sralph * suitability of this software for any purpose. It is provided "as is"
4956815Sralph * without express or implied warranty.
5056815Sralph *
5156815Sralph * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
5256815Sralph * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
5356815Sralph */
5456815Sralph
5556815Sralph #include <mfb.h>
5656815Sralph #if NMFB > 0
5756815Sralph #include <sys/param.h>
5856815Sralph #include <sys/time.h>
5956815Sralph #include <sys/kernel.h>
6056815Sralph #include <sys/ioctl.h>
6156815Sralph #include <sys/file.h>
6256815Sralph #include <sys/errno.h>
6356815Sralph #include <sys/proc.h>
6456815Sralph #include <sys/mman.h>
6556815Sralph
6656815Sralph #include <vm/vm.h>
6756815Sralph
6856815Sralph #include <machine/machConst.h>
6956815Sralph #include <machine/pmioctl.h>
7056815Sralph
7156815Sralph #include <pmax/pmax/cons.h>
7256815Sralph #include <pmax/pmax/pmaxtype.h>
7356815Sralph
7456815Sralph #include <pmax/dev/device.h>
7556815Sralph #include <pmax/dev/mfbreg.h>
7656815Sralph #include <pmax/dev/fbreg.h>
7756815Sralph
7856815Sralph #include <dc.h>
7956815Sralph #include <dtop.h>
8056815Sralph #include <scc.h>
8156815Sralph
8256815Sralph /*
8356815Sralph * These need to be mapped into user space.
8456815Sralph */
8556815Sralph struct fbuaccess mfbu;
8656815Sralph struct pmax_fb mfbfb;
8756815Sralph
8856815Sralph /*
8956815Sralph * Forward references.
9056815Sralph */
9156815Sralph static void mfbScreenInit();
9256815Sralph static void mfbLoadCursor();
9356815Sralph static void mfbRestoreCursorColor();
9456815Sralph static void mfbCursorColor();
9556815Sralph void mfbPosCursor();
9656815Sralph static void mfbInitColorMap();
9756815Sralph static void mfbLoadColorMap();
9856815Sralph static void mfbConfigMouse(), mfbDeconfigMouse();
9956815Sralph static void bt455_video_on(), bt455_video_off(), bt431_select_reg();
10056815Sralph static void bt431_write_reg(), bt431_init();
10156815Sralph static u_char bt431_read_reg();
10256815Sralph
10356815Sralph void mfbKbdEvent(), mfbMouseEvent(), mfbMouseButtons();
10456815Sralph #if NDC > 0
10556815Sralph extern void (*dcDivertXInput)();
10656815Sralph extern void (*dcMouseEvent)();
10756815Sralph extern void (*dcMouseButtons)();
10856815Sralph #endif
10956815Sralph #if NSCC > 0
11056815Sralph extern void (*sccDivertXInput)();
11156815Sralph extern void (*sccMouseEvent)();
11256815Sralph extern void (*sccMouseButtons)();
11356815Sralph #endif
11456815Sralph #if NDTOP > 0
11556815Sralph extern void (*dtopDivertXInput)();
11656815Sralph extern void (*dtopMouseEvent)();
11756815Sralph extern void (*dtopMouseButtons)();
11856815Sralph #endif
11956815Sralph extern int pmax_boardtype;
12056815Sralph extern u_short defCursor[32];
12156815Sralph extern struct consdev cn_tab;
12256815Sralph
12356815Sralph int mfbprobe();
12456815Sralph struct driver mfbdriver = {
12556815Sralph "mfb", mfbprobe, 0, 0,
12656815Sralph };
12756815Sralph
12856815Sralph #define MFB_OFFSET_VRAM 0x200000 /* from module's base */
12956815Sralph #define MFB_OFFSET_BT431 0x180000 /* Bt431 registers */
13056815Sralph #define MFB_OFFSET_BT455 0x100000 /* Bt455 registers */
13156815Sralph #define MFB_OFFSET_IREQ 0x080000 /* Interrupt req. control */
13256815Sralph #define MFB_OFFSET_ROM 0x0 /* Diagnostic ROM */
13359069Sralph #define MFB_FB_SIZE 0x200000 /* frame buffer size */
13456815Sralph
13556815Sralph /*
13656815Sralph * Test to see if device is present.
13756815Sralph * Return true if found and initialized ok.
13856815Sralph */
13956815Sralph /*ARGSUSED*/
mfbprobe(cp)14056815Sralph mfbprobe(cp)
14156815Sralph register struct pmax_ctlr *cp;
14256815Sralph {
14356815Sralph register struct pmax_fb *fp = &mfbfb;
14456815Sralph
14556815Sralph if (!fp->initialized && !mfbinit(cp->pmax_addr))
14656815Sralph return (0);
14756815Sralph printf("mfb0 (mono display)\n");
14856815Sralph return (1);
14956815Sralph }
15056815Sralph
15156815Sralph /*ARGSUSED*/
mfbopen(dev,flag)15256815Sralph mfbopen(dev, flag)
15356815Sralph dev_t dev;
15456815Sralph int flag;
15556815Sralph {
15656815Sralph register struct pmax_fb *fp = &mfbfb;
15756815Sralph int s;
15856815Sralph
15956815Sralph if (!fp->initialized)
16056815Sralph return (ENXIO);
16156815Sralph if (fp->GraphicsOpen)
16256815Sralph return (EBUSY);
16356815Sralph
16456815Sralph fp->GraphicsOpen = 1;
16558793Sralph mfbInitColorMap(1);
16656815Sralph /*
16756815Sralph * Set up event queue for later
16856815Sralph */
16956815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
17056815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
17156815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
17256815Sralph fp->fbu->scrInfo.qe.tcNext = 0;
17356815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
17456815Sralph mfbConfigMouse();
17556815Sralph return (0);
17656815Sralph }
17756815Sralph
17856815Sralph /*ARGSUSED*/
mfbclose(dev,flag)17956815Sralph mfbclose(dev, flag)
18056815Sralph dev_t dev;
18156815Sralph int flag;
18256815Sralph {
18356815Sralph register struct pmax_fb *fp = &mfbfb;
18456815Sralph int s;
18556815Sralph
18656815Sralph if (!fp->GraphicsOpen)
18756815Sralph return (EBADF);
18856815Sralph
18956815Sralph fp->GraphicsOpen = 0;
19058793Sralph mfbInitColorMap(0);
19156815Sralph mfbDeconfigMouse();
19256815Sralph mfbScreenInit();
19358793Sralph bzero((caddr_t)fp->fr_addr, 2048 * 1024);
19456815Sralph mfbPosCursor(fp->col * 8, fp->row * 15);
19556815Sralph return (0);
19656815Sralph }
19756815Sralph
19856815Sralph /*ARGSUSED*/
mfbioctl(dev,cmd,data,flag,p)19958974Sralph mfbioctl(dev, cmd, data, flag, p)
20056815Sralph dev_t dev;
201*69799Sralph u_long cmd;
20256815Sralph caddr_t data;
20358974Sralph struct proc *p;
20456815Sralph {
20556815Sralph register struct pmax_fb *fp = &mfbfb;
20656815Sralph int s;
20756815Sralph
20856815Sralph switch (cmd) {
20956815Sralph case QIOCGINFO:
21058974Sralph return (fbmmap(fp, dev, data, p));
21156815Sralph
21256815Sralph case QIOCPMSTATE:
21356815Sralph /*
21456815Sralph * Set mouse state.
21556815Sralph */
21656815Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data;
21756815Sralph mfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
21856815Sralph break;
21956815Sralph
22056815Sralph case QIOCINIT:
22156815Sralph /*
22256815Sralph * Initialize the screen.
22356815Sralph */
22456815Sralph mfbScreenInit();
22556815Sralph break;
22656815Sralph
22756815Sralph case QIOCKPCMD:
22856815Sralph {
22956815Sralph pmKpCmd *kpCmdPtr;
23056815Sralph unsigned char *cp;
23156815Sralph
23256815Sralph kpCmdPtr = (pmKpCmd *)data;
23356815Sralph if (kpCmdPtr->nbytes == 0)
23456815Sralph kpCmdPtr->cmd |= 0x80;
23556815Sralph if (!fp->GraphicsOpen)
23656815Sralph kpCmdPtr->cmd |= 1;
23756815Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
23856815Sralph cp = &kpCmdPtr->par[0];
23956815Sralph for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
24056815Sralph if (kpCmdPtr->nbytes == 1)
24156815Sralph *cp |= 0x80;
24256815Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp);
24356815Sralph }
24458974Sralph break;
24556815Sralph }
24656815Sralph
24756815Sralph case QIOCADDR:
24856815Sralph *(PM_Info **)data = &fp->fbu->scrInfo;
24956815Sralph break;
25056815Sralph
25156815Sralph case QIOWCURSOR:
25256815Sralph mfbLoadCursor((unsigned short *)data);
25356815Sralph break;
25456815Sralph
25556815Sralph case QIOWCURSORCOLOR:
25656815Sralph mfbCursorColor((unsigned int *)data);
25756815Sralph break;
25856815Sralph
25956815Sralph case QIOSETCMAP:
26058793Sralph #ifdef notdef
26156815Sralph mfbLoadColorMap((ColorMap *)data);
26258793Sralph #endif
26356815Sralph break;
26456815Sralph
26556815Sralph case QIOKERNLOOP:
26656815Sralph mfbConfigMouse();
26756815Sralph break;
26856815Sralph
26956815Sralph case QIOKERNUNLOOP:
27056815Sralph mfbDeconfigMouse();
27156815Sralph break;
27256815Sralph
27356815Sralph case QIOVIDEOON:
27456815Sralph bt455_video_on();
27556815Sralph break;
27656815Sralph
27756815Sralph case QIOVIDEOOFF:
27856815Sralph bt455_video_off();
27956815Sralph break;
28056815Sralph
28156815Sralph default:
28256815Sralph printf("mfb0: Unknown ioctl command %x\n", cmd);
28356815Sralph return (EINVAL);
28456815Sralph }
28556815Sralph return (0);
28656815Sralph }
28756815Sralph
28858974Sralph /*
28958974Sralph * Return the physical page number that corresponds to byte offset 'off'.
29058974Sralph */
29158974Sralph /*ARGSUSED*/
mfbmap(dev,off,prot)29258974Sralph mfbmap(dev, off, prot)
29358974Sralph dev_t dev;
29458974Sralph {
29558974Sralph int len;
29658974Sralph
29758974Sralph len = pmax_round_page(((vm_offset_t)&mfbu & PGOFSET) + sizeof(mfbu));
29858974Sralph if (off < len)
29958974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&mfbu) + off);
30058974Sralph off -= len;
30158974Sralph if (off >= mfbfb.fr_size)
30258974Sralph return (-1);
30358974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(mfbfb.fr_addr) + off);
30458974Sralph }
30558974Sralph
mfbselect(dev,flag,p)30656815Sralph mfbselect(dev, flag, p)
30756815Sralph dev_t dev;
30856815Sralph int flag;
30956815Sralph struct proc *p;
31056815Sralph {
31156815Sralph struct pmax_fb *fp = &mfbfb;
31256815Sralph
31356815Sralph switch (flag) {
31456815Sralph case FREAD:
31556815Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
31656815Sralph return (1);
31756815Sralph selrecord(p, &fp->selp);
31856815Sralph break;
31956815Sralph }
32056815Sralph
32156815Sralph return (0);
32256815Sralph }
32356815Sralph
32456815Sralph static u_char cursor_RGB[6]; /* cursor color 2 & 3 */
32556815Sralph
32656815Sralph /*
32756815Sralph * There are actually 2 Bt431 cursor sprite chips that each generate 1 bit
32856815Sralph * of each cursor pixel for a 2bit 64x64 cursor sprite. The corresponding
32956815Sralph * registers for these two chips live in adjacent bytes of the shorts that
33056815Sralph * are defined in bt431_regmap_t.
33156815Sralph */
33256815Sralph static void
mfbLoadCursor(cursor)33356815Sralph mfbLoadCursor(cursor)
33456815Sralph u_short *cursor;
33556815Sralph {
33656815Sralph register int i, j, k, pos;
33756815Sralph register u_short ap, bp, out;
33856815Sralph register bt431_regmap_t *regs;
33956815Sralph
34058793Sralph regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
34158793Sralph MFB_OFFSET_BT431);
34256815Sralph /*
34356815Sralph * Fill in the cursor sprite using the A and B planes, as provided
34456815Sralph * for the pmax.
34556815Sralph * XXX This will have to change when the X server knows that this
34658793Sralph * is not a pmax display. (ie. Not the Xcfbpmax server.)
34756815Sralph */
34856815Sralph pos = 0;
34956815Sralph bt431_select_reg(regs, BT431_REG_CRAM_BASE);
35056815Sralph for (k = 0; k < 16; k++) {
35156815Sralph ap = *cursor;
35256815Sralph bp = *(cursor + 16);
35356815Sralph j = 0;
35456815Sralph while (j < 2) {
35556815Sralph out = 0;
35656815Sralph for (i = 0; i < 8; i++) {
35758793Sralph out = (out << 1) | ((bp & 0x1) << 8) |
35858793Sralph (ap & 0x1);
35956815Sralph ap >>= 1;
36056815Sralph bp >>= 1;
36156815Sralph }
36256815Sralph BT431_WRITE_CMAP_AUTOI(regs, out);
36356815Sralph pos++;
36456815Sralph j++;
36556815Sralph }
36656815Sralph while (j < 8) {
36756815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0);
36856815Sralph pos++;
36956815Sralph j++;
37056815Sralph }
37156815Sralph cursor++;
37256815Sralph }
37356815Sralph while (pos < 512) {
37456815Sralph BT431_WRITE_CMAP_AUTOI(regs, 0);
37556815Sralph pos++;
37656815Sralph }
37756815Sralph }
37856815Sralph
37956815Sralph /*
38056815Sralph * Initialization
38156815Sralph */
38256815Sralph int
mfbinit(cp)38356815Sralph mfbinit(cp)
38456815Sralph char *cp;
38556815Sralph {
38656815Sralph register struct pmax_fb *fp = &mfbfb;
38756815Sralph
38856815Sralph /* check for no frame buffer */
38956815Sralph if (badaddr(cp, 4))
39056815Sralph return (0);
39156815Sralph
39258793Sralph fp->isMono = 0;
39358793Sralph fp->fr_addr = cp + MFB_OFFSET_VRAM;
39458793Sralph fp->fr_chipaddr = cp;
39558974Sralph fp->fr_size = MFB_FB_SIZE;
39657234Sralph /*
39758974Sralph * Must be in Uncached space since the fbuaccess structure is
39858974Sralph * mapped into the user's address space uncached.
39957234Sralph */
40057234Sralph fp->fbu = (struct fbuaccess *)
40157234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&mfbu));
40256815Sralph fp->posCursor = mfbPosCursor;
40357234Sralph if (tb_kbdmouseconfig(fp))
40456815Sralph return (0);
40556815Sralph
40656815Sralph /*
40756815Sralph * Initialize the screen.
40856815Sralph */
40958793Sralph bt431_init(fp->fr_chipaddr + MFB_OFFSET_BT431);
41056815Sralph
41156815Sralph /*
41256815Sralph * Initialize screen info.
41356815Sralph */
41456815Sralph fp->fbu->scrInfo.max_row = 67;
41556815Sralph fp->fbu->scrInfo.max_col = 80;
41656815Sralph fp->fbu->scrInfo.max_x = 1280;
41756815Sralph fp->fbu->scrInfo.max_y = 1024;
41856815Sralph fp->fbu->scrInfo.max_cur_x = 1279;
41956815Sralph fp->fbu->scrInfo.max_cur_y = 1023;
42056815Sralph fp->fbu->scrInfo.version = 11;
42156815Sralph fp->fbu->scrInfo.mthreshold = 4;
42256815Sralph fp->fbu->scrInfo.mscale = 2;
42356815Sralph fp->fbu->scrInfo.min_cur_x = 0;
42456815Sralph fp->fbu->scrInfo.min_cur_y = 0;
42556815Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
42656815Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
42756815Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
42856815Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
42956815Sralph fp->fbu->scrInfo.qe.tcNext = 0;
43056815Sralph
43156815Sralph /*
43256815Sralph * Initialize the color map, the screen, and the mouse.
43356815Sralph */
43458793Sralph mfbInitColorMap(0);
43556815Sralph mfbScreenInit();
43656815Sralph fbScroll(fp);
43756815Sralph
43856815Sralph fp->initialized = 1;
43956815Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0)
44056815Sralph cn_tab.cn_fb = fp;
44156815Sralph return (1);
44256815Sralph }
44356815Sralph
44456815Sralph /*
44556815Sralph * ----------------------------------------------------------------------------
44656815Sralph *
44756815Sralph * mfbScreenInit --
44856815Sralph *
44956815Sralph * Initialize the screen.
45056815Sralph *
45156815Sralph * Results:
45256815Sralph * None.
45356815Sralph *
45456815Sralph * Side effects:
45556815Sralph * The screen is initialized.
45656815Sralph *
45756815Sralph * ----------------------------------------------------------------------------
45856815Sralph */
45956815Sralph static void
mfbScreenInit()46056815Sralph mfbScreenInit()
46156815Sralph {
46256815Sralph register struct pmax_fb *fp = &mfbfb;
46356815Sralph
46456815Sralph /*
46556815Sralph * Home the cursor.
46656815Sralph * We want an LSI terminal emulation. We want the graphics
46756815Sralph * terminal to scroll from the bottom. So start at the bottom.
46856815Sralph */
46956815Sralph fp->row = 66;
47056815Sralph fp->col = 0;
47156815Sralph
47256815Sralph /*
47356815Sralph * Load the cursor with the default values
47456815Sralph *
47556815Sralph */
47656815Sralph mfbLoadCursor(defCursor);
47756815Sralph }
47856815Sralph
47956815Sralph /*
48056815Sralph * ----------------------------------------------------------------------------
48156815Sralph *
48256815Sralph * RestoreCursorColor --
48356815Sralph *
48456815Sralph * Routine to restore the color of the cursor.
48556815Sralph *
48656815Sralph * Results:
48756815Sralph * None.
48856815Sralph *
48956815Sralph * Side effects:
49056815Sralph * None.
49156815Sralph *
49256815Sralph * ----------------------------------------------------------------------------
49356815Sralph */
49456815Sralph static void
mfbRestoreCursorColor()49556815Sralph mfbRestoreCursorColor()
49656815Sralph {
49758793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
49858793Sralph MFB_OFFSET_BT455);
49956815Sralph ColorMap cm;
50058793Sralph u_char fg;
50156815Sralph
50258793Sralph if (cursor_RGB[0] || cursor_RGB[1] || cursor_RGB[2])
50358793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
50458793Sralph else
50558793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
50656815Sralph cm.index = 8;
50756815Sralph mfbLoadColorMap(&cm);
50856815Sralph cm.index = 9;
50956815Sralph mfbLoadColorMap(&cm);
51056815Sralph
51158793Sralph if (cursor_RGB[3] || cursor_RGB[4] || cursor_RGB[5])
51258793Sralph fg = 0xf;
51358793Sralph else
51458793Sralph fg = 0;
51558793Sralph regs->addr_ovly = fg;
51656815Sralph MachEmptyWriteBuffer();
51758793Sralph regs->addr_ovly = fg;
51856815Sralph MachEmptyWriteBuffer();
51958793Sralph regs->addr_ovly = fg;
52056815Sralph MachEmptyWriteBuffer();
52156815Sralph }
52256815Sralph
52356815Sralph /*
52456815Sralph * ----------------------------------------------------------------------------
52556815Sralph *
52656815Sralph * CursorColor --
52756815Sralph *
52856815Sralph * Set the color of the cursor.
52956815Sralph *
53056815Sralph * Results:
53156815Sralph * None.
53256815Sralph *
53356815Sralph * Side effects:
53456815Sralph * None.
53556815Sralph *
53656815Sralph * ----------------------------------------------------------------------------
53756815Sralph */
53856815Sralph static void
mfbCursorColor(color)53956815Sralph mfbCursorColor(color)
54056815Sralph unsigned int color[];
54156815Sralph {
54256815Sralph register int i, j;
54356815Sralph
54456815Sralph for (i = 0; i < 6; i++)
54556815Sralph cursor_RGB[i] = (u_char)(color[i] >> 8);
54656815Sralph
54756815Sralph mfbRestoreCursorColor();
54856815Sralph }
54956815Sralph
55056815Sralph /*
55156815Sralph *----------------------------------------------------------------------
55256815Sralph *
55356815Sralph * PosCursor --
55456815Sralph *
55556815Sralph * Postion the cursor.
55656815Sralph *
55756815Sralph * Results:
55856815Sralph * None.
55956815Sralph *
56056815Sralph * Side effects:
56156815Sralph * None.
56256815Sralph *
56356815Sralph *----------------------------------------------------------------------
56456815Sralph */
56556815Sralph void
mfbPosCursor(x,y)56656815Sralph mfbPosCursor(x, y)
56756815Sralph register int x, y;
56856815Sralph {
56958793Sralph bt431_regmap_t *regs = (bt431_regmap_t *)(mfbfb.fr_chipaddr +
57058793Sralph MFB_OFFSET_BT431);
57156815Sralph register struct pmax_fb *fp = &mfbfb;
57256815Sralph
57356815Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
57456815Sralph y = fp->fbu->scrInfo.max_cur_y;
57556815Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
57656815Sralph x = fp->fbu->scrInfo.max_cur_x;
57756815Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
57856815Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
57956815Sralph
58056815Sralph #define lo(v) ((v)&0xff)
58156815Sralph #define hi(v) (((v)&0xf00)>>8)
58256815Sralph
58356815Sralph /*
58456815Sralph * Cx = x + D + H - P
58556815Sralph * P = 37 if 1:1, 52 if 4:1, 57 if 5:1
58656815Sralph * D = pixel skew between outdata and external data
58756815Sralph * H = pixels between HSYNCH falling and active video
58856815Sralph *
58956815Sralph * Cy = y + V - 32
59056815Sralph * V = scanlines between HSYNCH falling, two or more
59156815Sralph * clocks after VSYNCH falling, and active video
59256815Sralph */
59356815Sralph
59458793Sralph bt431_write_reg(regs, BT431_REG_CXLO, lo(x + 360));
59556815Sralph BT431_WRITE_REG_AUTOI(regs, hi(x + 360));
59656815Sralph BT431_WRITE_REG_AUTOI(regs, lo(y + 36));
59756815Sralph BT431_WRITE_REG_AUTOI(regs, hi(y + 36));
59856815Sralph }
59956815Sralph
60056815Sralph /*
60156815Sralph * ----------------------------------------------------------------------------
60256815Sralph *
60356815Sralph * InitColorMap --
60456815Sralph *
60556815Sralph * Initialize the color map.
60656815Sralph *
60756815Sralph * Results:
60856815Sralph * None.
60956815Sralph *
61056815Sralph * Side effects:
61156815Sralph * The colormap is initialized appropriately.
61256815Sralph *
61356815Sralph * ----------------------------------------------------------------------------
61456815Sralph */
61556815Sralph static void
mfbInitColorMap(blackpix)61658793Sralph mfbInitColorMap(blackpix)
61758793Sralph int blackpix;
61856815Sralph {
61956815Sralph ColorMap cm;
62056815Sralph register int i;
62156815Sralph
62256815Sralph cm.index = 0;
62358793Sralph if (blackpix)
62458793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
62558793Sralph else
62658793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
62756815Sralph mfbLoadColorMap(&cm);
62858793Sralph if (blackpix)
62958793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
63058793Sralph else
63158793Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0xffff;
63256815Sralph for (i = 1; i < 16; i++) {
63356815Sralph cm.index = i;
63456815Sralph mfbLoadColorMap(&cm);
63556815Sralph }
63656815Sralph
63756815Sralph for (i = 0; i < 3; i++) {
63858793Sralph cursor_RGB[i] = 0;
63956815Sralph cursor_RGB[i + 3] = 0xff;
64056815Sralph }
64156815Sralph mfbRestoreCursorColor();
64256815Sralph }
64356815Sralph
64456815Sralph /*
64556815Sralph * ----------------------------------------------------------------------------
64656815Sralph *
64756815Sralph * LoadColorMap --
64856815Sralph *
64956815Sralph * Load the color map.
65056815Sralph *
65156815Sralph * Results:
65256815Sralph * None.
65356815Sralph *
65456815Sralph * Side effects:
65556815Sralph * The color map is loaded.
65656815Sralph *
65756815Sralph * ----------------------------------------------------------------------------
65856815Sralph */
65956815Sralph static void
mfbLoadColorMap(ptr)66056815Sralph mfbLoadColorMap(ptr)
66156815Sralph ColorMap *ptr;
66256815Sralph {
66358793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
66458793Sralph MFB_OFFSET_BT455);
66556815Sralph
66656815Sralph if (ptr->index > 15)
66756815Sralph return;
66856815Sralph
66956815Sralph BT455_SELECT_ENTRY(regs, ptr->index);
67056815Sralph regs->addr_cmap_data = ptr->Entry.red >> 12;
67156815Sralph MachEmptyWriteBuffer();
67256815Sralph regs->addr_cmap_data = ptr->Entry.green >> 12;
67356815Sralph MachEmptyWriteBuffer();
67456815Sralph regs->addr_cmap_data = ptr->Entry.blue >> 12;
67556815Sralph MachEmptyWriteBuffer();
67656815Sralph }
67756815Sralph
67856815Sralph /*
67956815Sralph * Video on/off state.
68056815Sralph */
68156815Sralph static struct vstate {
68256815Sralph u_char color0[6]; /* saved color map entry zero */
68356815Sralph u_char off; /* TRUE if display is off */
68458793Sralph u_char cursor[6]; /* saved cursor color */
68556815Sralph } vstate;
68656815Sralph
68756815Sralph /*
68856815Sralph * ----------------------------------------------------------------------------
68956815Sralph *
69056815Sralph * bt455_video_on
69156815Sralph *
69256815Sralph * Enable the video display.
69356815Sralph *
69456815Sralph * Results:
69556815Sralph * None.
69656815Sralph *
69756815Sralph * Side effects:
69856815Sralph * The display is enabled.
69956815Sralph *
70056815Sralph * ----------------------------------------------------------------------------
70156815Sralph */
70256815Sralph static void
bt455_video_on()70356815Sralph bt455_video_on()
70456815Sralph {
70558793Sralph register int i;
70658793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
70758793Sralph MFB_OFFSET_BT455);
70856815Sralph
70956815Sralph if (!vstate.off)
71056815Sralph return;
71156815Sralph
71256815Sralph /* restore old color map entry zero */
71356815Sralph BT455_SELECT_ENTRY(regs, 0);
71458793Sralph for (i = 0; i < 6; i++) {
71558793Sralph regs->addr_cmap_data = vstate.color0[i];
71658793Sralph MachEmptyWriteBuffer();
71758793Sralph cursor_RGB[i] = vstate.cursor[i];
71858793Sralph }
71958793Sralph mfbRestoreCursorColor();
72056815Sralph vstate.off = 0;
72156815Sralph }
72256815Sralph
72356815Sralph /*
72456815Sralph * ----------------------------------------------------------------------------
72556815Sralph *
72656815Sralph * bt455_video_off
72756815Sralph *
72856815Sralph * Disable the video display.
72956815Sralph *
73056815Sralph * Results:
73156815Sralph * None.
73256815Sralph *
73356815Sralph * Side effects:
73456815Sralph * The display is disabled.
73556815Sralph *
73656815Sralph * ----------------------------------------------------------------------------
73756815Sralph */
73856815Sralph static void
bt455_video_off()73956815Sralph bt455_video_off()
74056815Sralph {
74158793Sralph register int i;
74258793Sralph bt455_regmap_t *regs = (bt455_regmap_t *)(mfbfb.fr_chipaddr +
74358793Sralph MFB_OFFSET_BT455);
74456815Sralph ColorMap cm;
74556815Sralph
74656815Sralph if (vstate.off)
74756815Sralph return;
74856815Sralph
74956815Sralph /* save old color map entry zero */
75056815Sralph BT455_SELECT_ENTRY(regs, 0);
75158793Sralph for (i = 0; i < 6; i++) {
75258793Sralph vstate.color0[i] = regs->addr_cmap_data;
75358793Sralph vstate.cursor[i] = cursor_RGB[i];
75458793Sralph cursor_RGB[i] = 0;
75558793Sralph }
75656815Sralph
75756815Sralph /* set color map entry zero to zero */
75856815Sralph cm.index = 0;
75956815Sralph cm.Entry.red = cm.Entry.green = cm.Entry.blue = 0;
76056815Sralph mfbLoadColorMap(&cm);
76156815Sralph cm.index = 1;
76256815Sralph mfbLoadColorMap(&cm);
76356815Sralph
76458793Sralph mfbRestoreCursorColor();
76556815Sralph vstate.off = 1;
76656815Sralph }
76756815Sralph
76856815Sralph /*
76956815Sralph * mfb keyboard and mouse input. Just punt to the generic ones in fb.c
77056815Sralph */
77156815Sralph void
mfbKbdEvent(ch)77256815Sralph mfbKbdEvent(ch)
77356815Sralph int ch;
77456815Sralph {
77556815Sralph fbKbdEvent(ch, &mfbfb);
77656815Sralph }
77756815Sralph
77856815Sralph void
mfbMouseEvent(newRepPtr)77956815Sralph mfbMouseEvent(newRepPtr)
78056815Sralph MouseReport *newRepPtr;
78156815Sralph {
78256815Sralph fbMouseEvent(newRepPtr, &mfbfb);
78356815Sralph }
78456815Sralph
78556815Sralph void
mfbMouseButtons(newRepPtr)78656815Sralph mfbMouseButtons(newRepPtr)
78756815Sralph MouseReport *newRepPtr;
78856815Sralph {
78956815Sralph fbMouseButtons(newRepPtr, &mfbfb);
79056815Sralph }
79156815Sralph
79256815Sralph /*
79356815Sralph * Configure the mouse and keyboard based on machine type
79456815Sralph */
79556815Sralph static void
mfbConfigMouse()79656815Sralph mfbConfigMouse()
79756815Sralph {
79856815Sralph int s;
79956815Sralph
80056815Sralph s = spltty();
80156815Sralph switch (pmax_boardtype) {
80256815Sralph #if NDC > 0
80356815Sralph case DS_3MAX:
80456815Sralph dcDivertXInput = mfbKbdEvent;
80556815Sralph dcMouseEvent = mfbMouseEvent;
80656815Sralph dcMouseButtons = mfbMouseButtons;
80756815Sralph break;
80856815Sralph #endif
80956815Sralph #if NSCC > 1
81056815Sralph case DS_3MIN:
81156815Sralph sccDivertXInput = mfbKbdEvent;
81256815Sralph sccMouseEvent = mfbMouseEvent;
81356815Sralph sccMouseButtons = mfbMouseButtons;
81456815Sralph break;
81556815Sralph #endif
81656815Sralph #if NDTOP > 0
81756815Sralph case DS_MAXINE:
81856815Sralph dtopDivertXInput = mfbKbdEvent;
81956815Sralph dtopMouseEvent = mfbMouseEvent;
82056815Sralph dtopMouseButtons = mfbMouseButtons;
82156815Sralph break;
82256815Sralph #endif
82356815Sralph default:
82456815Sralph printf("Can't configure mouse/keyboard\n");
82556815Sralph };
82656815Sralph splx(s);
82756815Sralph }
82856815Sralph
82956815Sralph /*
83056815Sralph * and deconfigure them
83156815Sralph */
83256815Sralph static void
mfbDeconfigMouse()83356815Sralph mfbDeconfigMouse()
83456815Sralph {
83556815Sralph int s;
83656815Sralph
83756815Sralph s = spltty();
83856815Sralph switch (pmax_boardtype) {
83956815Sralph #if NDC > 0
84056815Sralph case DS_3MAX:
84156815Sralph dcDivertXInput = (void (*)())0;
84256815Sralph dcMouseEvent = (void (*)())0;
84356815Sralph dcMouseButtons = (void (*)())0;
84456815Sralph break;
84556815Sralph #endif
84656815Sralph #if NSCC > 1
84756815Sralph case DS_3MIN:
84856815Sralph sccDivertXInput = (void (*)())0;
84956815Sralph sccMouseEvent = (void (*)())0;
85056815Sralph sccMouseButtons = (void (*)())0;
85156815Sralph break;
85256815Sralph #endif
85356815Sralph #if NDTOP > 0
85456815Sralph case DS_MAXINE:
85556815Sralph dtopDivertXInput = (void (*)())0;
85656815Sralph dtopMouseEvent = (void (*)())0;
85756815Sralph dtopMouseButtons = (void (*)())0;
85856815Sralph break;
85956815Sralph #endif
86056815Sralph default:
86156815Sralph printf("Can't deconfigure mouse/keyboard\n");
86256815Sralph };
86356815Sralph }
86456815Sralph
86556815Sralph /*
86656815Sralph * Generic register access
86756815Sralph */
86856815Sralph static void
bt431_select_reg(regs,regno)86956815Sralph bt431_select_reg(regs, regno)
87056815Sralph bt431_regmap_t *regs;
87156815Sralph {
87256815Sralph regs->addr_lo = SET_VALUE(regno & 0xff);
87356815Sralph regs->addr_hi = SET_VALUE((regno >> 8) & 0xff);
87456815Sralph MachEmptyWriteBuffer();
87556815Sralph }
87656815Sralph
87756815Sralph static void
bt431_write_reg(regs,regno,val)87856815Sralph bt431_write_reg(regs, regno, val)
87956815Sralph bt431_regmap_t *regs;
88056815Sralph {
88156815Sralph bt431_select_reg(regs, regno);
88256815Sralph regs->addr_reg = SET_VALUE(val);
88356815Sralph MachEmptyWriteBuffer();
88456815Sralph }
88556815Sralph
88656815Sralph static u_char
bt431_read_reg(regs,regno)88756815Sralph bt431_read_reg(regs, regno)
88856815Sralph bt431_regmap_t *regs;
88956815Sralph {
89056815Sralph bt431_select_reg(regs, regno);
89156815Sralph return (GET_VALUE(regs->addr_reg));
89256815Sralph }
89356815Sralph
89456815Sralph static void
bt431_init(regs)89556815Sralph bt431_init(regs)
89656815Sralph bt431_regmap_t *regs;
89756815Sralph {
89856815Sralph register int i;
89956815Sralph
90056815Sralph /* use 4:1 input mux */
90156815Sralph bt431_write_reg(regs, BT431_REG_CMD,
90256815Sralph BT431_CMD_CURS_ENABLE|BT431_CMD_OR_CURSORS|
90356815Sralph BT431_CMD_4_1_MUX|BT431_CMD_THICK_1);
90456815Sralph
90556815Sralph /* home cursor */
90656815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
90756815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
90856815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
90956815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91056815Sralph
91156815Sralph /* no crosshair window */
91256815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91356815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91456815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91556815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91656815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91756815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91856815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
91956815Sralph BT431_WRITE_REG_AUTOI(regs, 0x00);
92056815Sralph }
92156815Sralph #endif /* NMFB */
922