152891Sbostic /*-
263205Sbostic * Copyright (c) 1992, 1993
363205Sbostic * The Regents of the University of California. All rights reserved.
452891Sbostic *
552891Sbostic * This code is derived from software contributed to Berkeley by
656819Sralph * Ralph Campbell and Rick Macklem.
752891Sbostic *
852891Sbostic * %sccs.include.redist.c%
952891Sbostic *
10*69799Sralph * @(#)cfb.c 8.2 (Berkeley) 06/02/95
1152891Sbostic */
1252891Sbostic
1352891Sbostic /*
1452891Sbostic * devGraphics.c --
1552891Sbostic *
1652891Sbostic * This file contains machine-dependent routines for the graphics device.
1752891Sbostic *
1852891Sbostic * Copyright (C) 1989 Digital Equipment Corporation.
1952891Sbostic * Permission to use, copy, modify, and distribute this software and
2052891Sbostic * its documentation for any purpose and without fee is hereby granted,
2152891Sbostic * provided that the above copyright notice appears in all copies.
2252891Sbostic * Digital Equipment Corporation makes no representations about the
2352891Sbostic * suitability of this software for any purpose. It is provided "as is"
2452891Sbostic * without express or implied warranty.
2552891Sbostic *
2652891Sbostic * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c,
2752891Sbostic * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)";
2852891Sbostic */
2952891Sbostic /*
3052891Sbostic * Mach Operating System
3152891Sbostic * Copyright (c) 1991,1990,1989 Carnegie Mellon University
3252891Sbostic * All Rights Reserved.
3352891Sbostic *
3452891Sbostic * Permission to use, copy, modify and distribute this software and its
3552891Sbostic * documentation is hereby granted, provided that both the copyright
3652891Sbostic * notice and this permission notice appear in all copies of the
3752891Sbostic * software, derivative works or modified versions, and any portions
3852891Sbostic * thereof, and that both notices appear in supporting documentation.
3952891Sbostic *
4052891Sbostic * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
4152891Sbostic * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
4252891Sbostic * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
4352891Sbostic *
4452891Sbostic * Carnegie Mellon requests users of this software to return to
4552891Sbostic *
4652891Sbostic * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
4752891Sbostic * School of Computer Science
4852891Sbostic * Carnegie Mellon University
4952891Sbostic * Pittsburgh PA 15213-3890
5052891Sbostic *
5152891Sbostic * any improvements or extensions that they make and grant Carnegie the
5252891Sbostic * rights to redistribute these changes.
5352891Sbostic */
5452891Sbostic
5556819Sralph #include <cfb.h>
5652891Sbostic #if NCFB > 0
5756522Sbostic #include <sys/param.h>
5856522Sbostic #include <sys/time.h>
5956522Sbostic #include <sys/kernel.h>
6056522Sbostic #include <sys/ioctl.h>
6156522Sbostic #include <sys/file.h>
6256522Sbostic #include <sys/errno.h>
6356522Sbostic #include <sys/proc.h>
6456522Sbostic #include <sys/mman.h>
6552891Sbostic
6656522Sbostic #include <vm/vm.h>
6752891Sbostic
6856522Sbostic #include <machine/machConst.h>
6956522Sbostic #include <machine/pmioctl.h>
7052891Sbostic
7156819Sralph #include <pmax/pmax/maxine.h>
7256819Sralph #include <pmax/pmax/cons.h>
7356819Sralph #include <pmax/pmax/pmaxtype.h>
7456819Sralph
7556525Sbostic #include <pmax/dev/device.h>
7656525Sbostic #include <pmax/dev/cfbreg.h>
7756819Sralph #include <pmax/dev/fbreg.h>
7856522Sbostic
7956819Sralph #include <dc.h>
8056819Sralph #include <dtop.h>
8156819Sralph #include <scc.h>
8252891Sbostic
8359070Sralph #define PMAX /* enable /dev/pm compatibility */
8459070Sralph
8552891Sbostic /*
8652891Sbostic * These need to be mapped into user space.
8752891Sbostic */
8856819Sralph struct fbuaccess cfbu;
8956819Sralph struct pmax_fb cfbfb;
9052891Sbostic
9152891Sbostic /*
9252891Sbostic * Forward references.
9352891Sbostic */
9456819Sralph static void cfbScreenInit();
9556819Sralph static void cfbLoadCursor();
9656819Sralph static void cfbRestoreCursorColor();
9756819Sralph static void cfbCursorColor();
9856819Sralph void cfbPosCursor();
9956819Sralph static void cfbInitColorMap();
10056819Sralph static void cfbLoadColorMap();
10156819Sralph static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off();
10256819Sralph static void bt459_select_reg(), bt459_write_reg();
10356819Sralph static u_char bt459_read_reg();
10456819Sralph static void cfbConfigMouse(), cfbDeconfigMouse();
10552891Sbostic
10656819Sralph void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons();
10756819Sralph #if NDC > 0
10852891Sbostic extern void (*dcDivertXInput)();
10952891Sbostic extern void (*dcMouseEvent)();
11052891Sbostic extern void (*dcMouseButtons)();
11156819Sralph #endif
11256819Sralph #if NSCC > 0
11356819Sralph extern void (*sccDivertXInput)();
11456819Sralph extern void (*sccMouseEvent)();
11556819Sralph extern void (*sccMouseButtons)();
11656819Sralph #endif
11756819Sralph #if NDTOP > 0
11856819Sralph extern void (*dtopDivertXInput)();
11956819Sralph extern void (*dtopMouseEvent)();
12056819Sralph extern void (*dtopMouseButtons)();
12156819Sralph #endif
12256819Sralph extern int pmax_boardtype;
12356819Sralph extern u_short defCursor[32];
12456819Sralph extern struct consdev cn_tab;
12552891Sbostic
12652891Sbostic int cfbprobe();
12752891Sbostic struct driver cfbdriver = {
12852891Sbostic "cfb", cfbprobe, 0, 0,
12952891Sbostic };
13052891Sbostic
13156819Sralph #define CFB_OFFSET_VRAM 0x0 /* from module's base */
13256819Sralph #define CFB_OFFSET_BT459 0x200000 /* Bt459 registers */
13356819Sralph #define CFB_OFFSET_IREQ 0x300000 /* Interrupt req. control */
13456819Sralph #define CFB_OFFSET_ROM 0x380000 /* Diagnostic ROM */
13556819Sralph #define CFB_OFFSET_RESET 0x3c0000 /* Bt459 resets on writes */
13658974Sralph #define CFB_FB_SIZE 0x100000 /* frame buffer size */
13756819Sralph
13852891Sbostic /*
13952891Sbostic * Test to see if device is present.
14052891Sbostic * Return true if found and initialized ok.
14152891Sbostic */
14256819Sralph /*ARGSUSED*/
cfbprobe(cp)14352891Sbostic cfbprobe(cp)
14452891Sbostic register struct pmax_ctlr *cp;
14552891Sbostic {
14656819Sralph register struct pmax_fb *fp = &cfbfb;
14752891Sbostic
14856819Sralph if (!fp->initialized && !cfbinit(cp->pmax_addr))
14956819Sralph return (0);
15056819Sralph printf("cfb0 (color display)\n");
15152891Sbostic return (1);
15252891Sbostic }
15352891Sbostic
15452891Sbostic /*ARGSUSED*/
cfbopen(dev,flag)15552891Sbostic cfbopen(dev, flag)
15652891Sbostic dev_t dev;
15752891Sbostic int flag;
15852891Sbostic {
15956819Sralph register struct pmax_fb *fp = &cfbfb;
16056819Sralph int s;
16152891Sbostic
16256819Sralph if (!fp->initialized)
16352891Sbostic return (ENXIO);
16456819Sralph if (fp->GraphicsOpen)
16552891Sbostic return (EBUSY);
16652891Sbostic
16756819Sralph fp->GraphicsOpen = 1;
16856819Sralph cfbInitColorMap();
16952891Sbostic /*
17052891Sbostic * Set up event queue for later
17152891Sbostic */
17256819Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
17356819Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
17456819Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
17556819Sralph fp->fbu->scrInfo.qe.tcNext = 0;
17656819Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
17756819Sralph cfbConfigMouse();
17852891Sbostic return (0);
17952891Sbostic }
18052891Sbostic
18152891Sbostic /*ARGSUSED*/
cfbclose(dev,flag)18252891Sbostic cfbclose(dev, flag)
18352891Sbostic dev_t dev;
18452891Sbostic int flag;
18552891Sbostic {
18656819Sralph register struct pmax_fb *fp = &cfbfb;
18752959Sralph int s;
18852891Sbostic
18956819Sralph if (!fp->GraphicsOpen)
19052891Sbostic return (EBADF);
19152891Sbostic
19256819Sralph fp->GraphicsOpen = 0;
19356819Sralph cfbInitColorMap();
19456819Sralph cfbDeconfigMouse();
19556819Sralph cfbScreenInit();
19656819Sralph bzero((caddr_t)fp->fr_addr, 1024 * 864);
19756819Sralph cfbPosCursor(fp->col * 8, fp->row * 15);
19852891Sbostic return (0);
19952891Sbostic }
20052891Sbostic
20152891Sbostic /*ARGSUSED*/
cfbioctl(dev,cmd,data,flag,p)20258974Sralph cfbioctl(dev, cmd, data, flag, p)
20352891Sbostic dev_t dev;
204*69799Sralph u_long cmd;
20552891Sbostic caddr_t data;
20658974Sralph struct proc *p;
20752891Sbostic {
20856819Sralph register struct pmax_fb *fp = &cfbfb;
20952959Sralph int s;
21052891Sbostic
21152891Sbostic switch (cmd) {
21252891Sbostic case QIOCGINFO:
21358974Sralph return (fbmmap(fp, dev, data, p));
21452891Sbostic
21552891Sbostic case QIOCPMSTATE:
21652891Sbostic /*
21752891Sbostic * Set mouse state.
21852891Sbostic */
21956819Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data;
22056819Sralph cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y);
22152891Sbostic break;
22252891Sbostic
22352891Sbostic case QIOCINIT:
22452891Sbostic /*
22552891Sbostic * Initialize the screen.
22652891Sbostic */
22756819Sralph cfbScreenInit();
22852891Sbostic break;
22952891Sbostic
23052891Sbostic case QIOCKPCMD:
23152891Sbostic {
23252891Sbostic pmKpCmd *kpCmdPtr;
23352891Sbostic unsigned char *cp;
23452891Sbostic
23552891Sbostic kpCmdPtr = (pmKpCmd *)data;
23652891Sbostic if (kpCmdPtr->nbytes == 0)
23752891Sbostic kpCmdPtr->cmd |= 0x80;
23856819Sralph if (!fp->GraphicsOpen)
23952891Sbostic kpCmdPtr->cmd |= 1;
24056819Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd);
24152891Sbostic cp = &kpCmdPtr->par[0];
24252891Sbostic for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) {
24352891Sbostic if (kpCmdPtr->nbytes == 1)
24452891Sbostic *cp |= 0x80;
24556819Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp);
24652891Sbostic }
24758974Sralph break;
24852891Sbostic }
24952891Sbostic
25052891Sbostic case QIOCADDR:
25156819Sralph *(PM_Info **)data = &fp->fbu->scrInfo;
25252891Sbostic break;
25352891Sbostic
25452891Sbostic case QIOWCURSOR:
25556819Sralph cfbLoadCursor((unsigned short *)data);
25652891Sbostic break;
25752891Sbostic
25852891Sbostic case QIOWCURSORCOLOR:
25956819Sralph cfbCursorColor((unsigned int *)data);
26052891Sbostic break;
26152891Sbostic
26252891Sbostic case QIOSETCMAP:
26356819Sralph cfbLoadColorMap((ColorMap *)data);
26452891Sbostic break;
26552891Sbostic
26652891Sbostic case QIOKERNLOOP:
26756819Sralph cfbConfigMouse();
26852891Sbostic break;
26952891Sbostic
27052891Sbostic case QIOKERNUNLOOP:
27156819Sralph cfbDeconfigMouse();
27252891Sbostic break;
27352891Sbostic
27452891Sbostic case QIOVIDEOON:
27556819Sralph cfbRestoreCursorColor();
27656819Sralph bt459_video_on();
27752891Sbostic break;
27852891Sbostic
27952891Sbostic case QIOVIDEOOFF:
28056819Sralph bt459_video_off();
28152891Sbostic break;
28252891Sbostic
28352891Sbostic default:
28452891Sbostic printf("cfb0: Unknown ioctl command %x\n", cmd);
28552891Sbostic return (EINVAL);
28652891Sbostic }
28752891Sbostic return (0);
28852891Sbostic }
28952891Sbostic
cfbselect(dev,flag,p)29052891Sbostic cfbselect(dev, flag, p)
29152891Sbostic dev_t dev;
29252891Sbostic int flag;
29352891Sbostic struct proc *p;
29452891Sbostic {
29556819Sralph struct pmax_fb *fp = &cfbfb;
29652891Sbostic
29752891Sbostic switch (flag) {
29852891Sbostic case FREAD:
29956819Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail)
30052891Sbostic return (1);
30156819Sralph selrecord(p, &fp->selp);
30252891Sbostic break;
30352891Sbostic }
30452891Sbostic
30552891Sbostic return (0);
30652891Sbostic }
30752891Sbostic
30858974Sralph /*
30958974Sralph * Return the physical page number that corresponds to byte offset 'off'.
31058974Sralph */
31158974Sralph /*ARGSUSED*/
cfbmap(dev,off,prot)31258974Sralph cfbmap(dev, off, prot)
31358974Sralph dev_t dev;
31458974Sralph {
31558974Sralph int len;
31658974Sralph
31758974Sralph len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu));
31858974Sralph if (off < len)
31958974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off);
32058974Sralph off -= len;
32158974Sralph if (off >= cfbfb.fr_size)
32258974Sralph return (-1);
32358974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off);
32458974Sralph }
32558974Sralph
32652891Sbostic static u_char cursor_RGB[6]; /* cursor color 2 & 3 */
32752891Sbostic
32852891Sbostic /*
32956819Sralph * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM
33056819Sralph * defines a 64x64 cursor. If the bt459 does not map the cursor RAM
33156819Sralph * this way, this code is Screwed!
33252891Sbostic */
33356819Sralph static void
cfbLoadCursor(cursor)33456819Sralph cfbLoadCursor(cursor)
33556819Sralph u_short *cursor;
33656819Sralph {
33759070Sralph #ifdef PMAX
33856819Sralph register int i, j, k, pos;
33956819Sralph register u_short ap, bp, out;
34052891Sbostic
34156819Sralph /*
34256819Sralph * Fill in the cursor sprite using the A and B planes, as provided
34356819Sralph * for the pmax.
34456819Sralph * XXX This will have to change when the X server knows that this
34556819Sralph * is not a pmax display.
34656819Sralph */
34756819Sralph pos = 0;
34856819Sralph for (k = 0; k < 16; k++) {
34956819Sralph ap = *cursor;
35056819Sralph bp = *(cursor + 16);
35156819Sralph j = 0;
35256819Sralph while (j < 4) {
35356819Sralph out = 0;
35456819Sralph for (i = 0; i < 4; i++) {
35559824Sralph #ifndef CURSOR_EB
35656819Sralph out = (out << 2) | ((ap & 0x1) << 1) |
35756819Sralph (bp & 0x1);
35857234Sralph #else
35957234Sralph out = ((out >> 2) & 0x3f) |
36057234Sralph ((ap & 0x1) << 7) |
36157234Sralph ((bp & 0x1) << 6);
36257234Sralph #endif
36356819Sralph ap >>= 1;
36456819Sralph bp >>= 1;
36556819Sralph }
36656819Sralph bt459_set_cursor_ram(pos, out);
36756819Sralph pos++;
36856819Sralph j++;
36956819Sralph }
37056819Sralph while (j < 16) {
37156819Sralph bt459_set_cursor_ram(pos, 0);
37256819Sralph pos++;
37356819Sralph j++;
37456819Sralph }
37556819Sralph cursor++;
37656819Sralph }
37756819Sralph while (pos < 1024) {
37856819Sralph bt459_set_cursor_ram(pos, 0);
37956819Sralph pos++;
38056819Sralph }
38159070Sralph #endif /* PMAX */
38256819Sralph }
38352891Sbostic
38452891Sbostic /*
38556819Sralph * Set a cursor ram value.
38656819Sralph */
38756819Sralph static void
bt459_set_cursor_ram(pos,val)38856819Sralph bt459_set_cursor_ram(pos, val)
38956819Sralph int pos;
39056819Sralph register u_char val;
39156819Sralph {
39256819Sralph register bt459_regmap_t *regs = (bt459_regmap_t *)
39356819Sralph (cfbfb.fr_addr + CFB_OFFSET_BT459);
39456819Sralph register int cnt;
39556819Sralph u_char nval;
39656819Sralph
39756819Sralph cnt = 0;
39856819Sralph do {
39956819Sralph bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val);
40056819Sralph nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos);
40156819Sralph } while (val != nval && ++cnt < 10);
40256819Sralph }
40356819Sralph
40456819Sralph /*
40552891Sbostic * Generic register access
40652891Sbostic */
40756819Sralph static void
bt459_select_reg(regs,regno)40852891Sbostic bt459_select_reg(regs, regno)
40952891Sbostic bt459_regmap_t *regs;
41052891Sbostic {
41152891Sbostic regs->addr_lo = regno;
41252891Sbostic regs->addr_hi = regno >> 8;
41352891Sbostic MachEmptyWriteBuffer();
41452891Sbostic }
41552891Sbostic
41656819Sralph static void
bt459_write_reg(regs,regno,val)41752891Sbostic bt459_write_reg(regs, regno, val)
41852891Sbostic bt459_regmap_t *regs;
41952891Sbostic {
42052891Sbostic regs->addr_lo = regno;
42152891Sbostic regs->addr_hi = regno >> 8;
42252891Sbostic MachEmptyWriteBuffer();
42352891Sbostic regs->addr_reg = val;
42452891Sbostic MachEmptyWriteBuffer();
42552891Sbostic }
42652891Sbostic
42756819Sralph static u_char
bt459_read_reg(regs,regno)42852891Sbostic bt459_read_reg(regs, regno)
42952891Sbostic bt459_regmap_t *regs;
43052891Sbostic {
43152891Sbostic regs->addr_lo = regno;
43252891Sbostic regs->addr_hi = regno >> 8;
43352891Sbostic MachEmptyWriteBuffer();
43456819Sralph return (regs->addr_reg);
43552891Sbostic }
43652891Sbostic
43752891Sbostic /*
43856819Sralph * Initialization
43952891Sbostic */
44056819Sralph int
cfbinit(cp)44156819Sralph cfbinit(cp)
44256819Sralph char *cp;
44352891Sbostic {
44456819Sralph register bt459_regmap_t *regs;
44556819Sralph register struct pmax_fb *fp = &cfbfb;
44652891Sbostic
44752891Sbostic /* check for no frame buffer */
44856819Sralph if (badaddr(cp, 4))
44952891Sbostic return (0);
45052891Sbostic
45156819Sralph fp->isMono = 0;
45256819Sralph fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM);
45358974Sralph fp->fr_size = CFB_FB_SIZE;
45457234Sralph /*
45558974Sralph * Must be in Uncached space since the fbuaccess structure is
45658974Sralph * mapped into the user's address space uncached.
45757234Sralph */
45857234Sralph fp->fbu = (struct fbuaccess *)
45957234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu));
46056819Sralph fp->posCursor = cfbPosCursor;
46157234Sralph if (tb_kbdmouseconfig(fp))
46256819Sralph return (0);
46352891Sbostic
46456819Sralph /*
46556819Sralph * Initialize the screen.
46656819Sralph */
46756819Sralph regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459);
46856819Sralph
46952891Sbostic if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a)
47052891Sbostic return (0);
47152891Sbostic
47256819Sralph /* Reset the chip */
47356819Sralph *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0;
47452891Sbostic DELAY(2000); /* ???? check right time on specs! ???? */
47552891Sbostic
47652891Sbostic /* use 4:1 input mux */
47752891Sbostic bt459_write_reg(regs, BT459_REG_CMD0, 0x40);
47852891Sbostic
47952891Sbostic /* no zooming, no panning */
48052891Sbostic bt459_write_reg(regs, BT459_REG_CMD1, 0x00);
48152891Sbostic
48252891Sbostic /*
48352891Sbostic * signature test, X-windows cursor, no overlays, SYNC* PLL,
48452891Sbostic * normal RAM select, 7.5 IRE pedestal, do sync
48552891Sbostic */
48659070Sralph #ifndef PMAX
48752891Sbostic bt459_write_reg(regs, BT459_REG_CMD2, 0xc2);
48859070Sralph #else /* PMAX */
48959070Sralph bt459_write_reg(regs, BT459_REG_CMD2, 0xc0);
49059070Sralph #endif /* PMAX */
49152891Sbostic
49252891Sbostic /* get all pixel bits */
49352891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff);
49452891Sbostic
49552891Sbostic /* no blinking */
49652891Sbostic bt459_write_reg(regs, BT459_REG_PBM, 0x00);
49752891Sbostic
49852891Sbostic /* no overlay */
49952891Sbostic bt459_write_reg(regs, BT459_REG_ORM, 0x00);
50052891Sbostic
50152891Sbostic /* no overlay blink */
50252891Sbostic bt459_write_reg(regs, BT459_REG_OBM, 0x00);
50352891Sbostic
50452891Sbostic /* no interleave, no underlay */
50552891Sbostic bt459_write_reg(regs, BT459_REG_ILV, 0x00);
50652891Sbostic
50752891Sbostic /* normal operation, no signature analysis */
50852891Sbostic bt459_write_reg(regs, BT459_REG_TEST, 0x00);
50952891Sbostic
51052891Sbostic /*
51152891Sbostic * no blinking, 1bit cross hair, XOR reg&crosshair,
51252891Sbostic * no crosshair on either plane 0 or 1,
51352891Sbostic * regular cursor on both planes.
51452891Sbostic */
51552891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
51652891Sbostic
51752891Sbostic /* home cursor */
51852891Sbostic bt459_write_reg(regs, BT459_REG_CXLO, 0x00);
51952891Sbostic bt459_write_reg(regs, BT459_REG_CXHI, 0x00);
52052891Sbostic bt459_write_reg(regs, BT459_REG_CYLO, 0x00);
52152891Sbostic bt459_write_reg(regs, BT459_REG_CYHI, 0x00);
52252891Sbostic
52352891Sbostic /* no crosshair window */
52452891Sbostic bt459_write_reg(regs, BT459_REG_WXLO, 0x00);
52552891Sbostic bt459_write_reg(regs, BT459_REG_WXHI, 0x00);
52652891Sbostic bt459_write_reg(regs, BT459_REG_WYLO, 0x00);
52752891Sbostic bt459_write_reg(regs, BT459_REG_WYHI, 0x00);
52852891Sbostic bt459_write_reg(regs, BT459_REG_WWLO, 0x00);
52952891Sbostic bt459_write_reg(regs, BT459_REG_WWHI, 0x00);
53052891Sbostic bt459_write_reg(regs, BT459_REG_WHLO, 0x00);
53152891Sbostic bt459_write_reg(regs, BT459_REG_WHHI, 0x00);
53252891Sbostic
53352891Sbostic /*
53452891Sbostic * Initialize screen info.
53552891Sbostic */
53656819Sralph fp->fbu->scrInfo.max_row = 56;
53756819Sralph fp->fbu->scrInfo.max_col = 80;
53856819Sralph fp->fbu->scrInfo.max_x = 1024;
53956819Sralph fp->fbu->scrInfo.max_y = 864;
54056819Sralph fp->fbu->scrInfo.max_cur_x = 1023;
54156819Sralph fp->fbu->scrInfo.max_cur_y = 863;
54256819Sralph fp->fbu->scrInfo.version = 11;
54356819Sralph fp->fbu->scrInfo.mthreshold = 4;
54456819Sralph fp->fbu->scrInfo.mscale = 2;
54556819Sralph fp->fbu->scrInfo.min_cur_x = 0;
54656819Sralph fp->fbu->scrInfo.min_cur_y = 0;
54756819Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time);
54856819Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ;
54956819Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0;
55056819Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE;
55156819Sralph fp->fbu->scrInfo.qe.tcNext = 0;
55252891Sbostic
55352891Sbostic /*
55452891Sbostic * Initialize the color map, the screen, and the mouse.
55552891Sbostic */
55656819Sralph cfbInitColorMap();
55756819Sralph cfbScreenInit();
55856819Sralph fbScroll(fp);
55952891Sbostic
56056819Sralph fp->initialized = 1;
56156819Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0)
56256819Sralph cn_tab.cn_fb = fp;
56352891Sbostic return (1);
56452891Sbostic }
56552891Sbostic
56652891Sbostic /*
56752891Sbostic * ----------------------------------------------------------------------------
56852891Sbostic *
56956819Sralph * cfbScreenInit --
57052891Sbostic *
57152891Sbostic * Initialize the screen.
57252891Sbostic *
57352891Sbostic * Results:
57452891Sbostic * None.
57552891Sbostic *
57652891Sbostic * Side effects:
57752891Sbostic * The screen is initialized.
57852891Sbostic *
57952891Sbostic * ----------------------------------------------------------------------------
58052891Sbostic */
58152891Sbostic static void
cfbScreenInit()58256819Sralph cfbScreenInit()
58352891Sbostic {
58456819Sralph register struct pmax_fb *fp = &cfbfb;
58552891Sbostic
58652891Sbostic /*
58752891Sbostic * Home the cursor.
58856819Sralph * We want an LSI terminal emulation. We want the graphics
58952891Sbostic * terminal to scroll from the bottom. So start at the bottom.
59052891Sbostic */
59156819Sralph fp->row = 55;
59256819Sralph fp->col = 0;
59352891Sbostic
59452891Sbostic /*
59552891Sbostic * Load the cursor with the default values
59652891Sbostic *
59752891Sbostic */
59856819Sralph cfbLoadCursor(defCursor);
59952891Sbostic }
60052891Sbostic
60152891Sbostic /*
60252891Sbostic * ----------------------------------------------------------------------------
60352891Sbostic *
60452891Sbostic * RestoreCursorColor --
60552891Sbostic *
60652891Sbostic * Routine to restore the color of the cursor.
60752891Sbostic *
60852891Sbostic * Results:
60952891Sbostic * None.
61052891Sbostic *
61152891Sbostic * Side effects:
61252891Sbostic * None.
61352891Sbostic *
61452891Sbostic * ----------------------------------------------------------------------------
61552891Sbostic */
61652891Sbostic static void
cfbRestoreCursorColor()61756819Sralph cfbRestoreCursorColor()
61852891Sbostic {
61956819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
62052891Sbostic register int i;
62152891Sbostic
62259070Sralph #ifndef PMAX
62352891Sbostic bt459_select_reg(regs, BT459_REG_CCOLOR_2);
62452891Sbostic for (i = 0; i < 6; i++) {
62552891Sbostic regs->addr_reg = cursor_RGB[i];
62652891Sbostic MachEmptyWriteBuffer();
62752891Sbostic }
62859070Sralph #else /* PMAX */
62959070Sralph bt459_select_reg(regs, BT459_REG_CCOLOR_1);
63059070Sralph for (i = 0; i < 3; i++) {
63159070Sralph regs->addr_reg = cursor_RGB[i];
63259070Sralph MachEmptyWriteBuffer();
63359070Sralph }
63459070Sralph bt459_select_reg(regs, BT459_REG_CCOLOR_3);
63559070Sralph for (i = 3; i < 6; i++) {
63659070Sralph regs->addr_reg = cursor_RGB[i];
63759070Sralph MachEmptyWriteBuffer();
63859070Sralph }
63959070Sralph #endif /* PMAX */
64052891Sbostic }
64152891Sbostic
64252891Sbostic /*
64352891Sbostic * ----------------------------------------------------------------------------
64452891Sbostic *
64552891Sbostic * CursorColor --
64652891Sbostic *
64752891Sbostic * Set the color of the cursor.
64852891Sbostic *
64952891Sbostic * Results:
65052891Sbostic * None.
65152891Sbostic *
65252891Sbostic * Side effects:
65352891Sbostic * None.
65452891Sbostic *
65552891Sbostic * ----------------------------------------------------------------------------
65652891Sbostic */
65752891Sbostic static void
cfbCursorColor(color)65856819Sralph cfbCursorColor(color)
65952891Sbostic unsigned int color[];
66052891Sbostic {
66152891Sbostic register int i, j;
66252891Sbostic
66352891Sbostic for (i = 0; i < 6; i++)
66452891Sbostic cursor_RGB[i] = (u_char)(color[i] >> 8);
66552891Sbostic
66656819Sralph cfbRestoreCursorColor();
66752891Sbostic }
66852891Sbostic
66952891Sbostic /*
67052891Sbostic *----------------------------------------------------------------------
67152891Sbostic *
67252891Sbostic * PosCursor --
67352891Sbostic *
67452891Sbostic * Postion the cursor.
67552891Sbostic *
67652891Sbostic * Results:
67752891Sbostic * None.
67852891Sbostic *
67952891Sbostic * Side effects:
68052891Sbostic * None.
68152891Sbostic *
68252891Sbostic *----------------------------------------------------------------------
68352891Sbostic */
68456819Sralph void
cfbPosCursor(x,y)68556819Sralph cfbPosCursor(x, y)
68652891Sbostic register int x, y;
68752891Sbostic {
68856819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
68956819Sralph register struct pmax_fb *fp = &cfbfb;
69052891Sbostic
69156819Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y)
69256819Sralph y = fp->fbu->scrInfo.max_cur_y;
69356819Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x)
69456819Sralph x = fp->fbu->scrInfo.max_cur_x;
69556819Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */
69656819Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */
69752891Sbostic
69852891Sbostic x += 219;
69952891Sbostic y += 34;
70052891Sbostic
70152891Sbostic bt459_select_reg(regs, BT459_REG_CXLO);
70252891Sbostic regs->addr_reg = x;
70352891Sbostic MachEmptyWriteBuffer();
70452891Sbostic regs->addr_reg = x >> 8;
70552891Sbostic MachEmptyWriteBuffer();
70652891Sbostic regs->addr_reg = y;
70752891Sbostic MachEmptyWriteBuffer();
70852891Sbostic regs->addr_reg = y >> 8;
70952891Sbostic MachEmptyWriteBuffer();
71052891Sbostic }
71152891Sbostic
71252891Sbostic /*
71352891Sbostic * ----------------------------------------------------------------------------
71452891Sbostic *
71552891Sbostic * InitColorMap --
71652891Sbostic *
71752891Sbostic * Initialize the color map.
71852891Sbostic *
71952891Sbostic * Results:
72052891Sbostic * None.
72152891Sbostic *
72252891Sbostic * Side effects:
72352891Sbostic * The colormap is initialized appropriately.
72452891Sbostic *
72552891Sbostic * ----------------------------------------------------------------------------
72652891Sbostic */
72752891Sbostic static void
cfbInitColorMap()72856819Sralph cfbInitColorMap()
72952891Sbostic {
73056819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
73152891Sbostic register int i;
73252891Sbostic
73352891Sbostic bt459_select_reg(regs, 0);
73452891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer();
73552891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer();
73652891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer();
73752891Sbostic
73852891Sbostic for (i = 1; i < 256; i++) {
73952891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74052891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74152891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer();
74252891Sbostic }
74352891Sbostic
74452891Sbostic for (i = 0; i < 3; i++) {
74552891Sbostic cursor_RGB[i] = 0x00;
74652891Sbostic cursor_RGB[i + 3] = 0xff;
74752891Sbostic }
74856819Sralph cfbRestoreCursorColor();
74952891Sbostic }
75052891Sbostic
75152891Sbostic /*
75252891Sbostic * ----------------------------------------------------------------------------
75352891Sbostic *
75452891Sbostic * LoadColorMap --
75552891Sbostic *
75652891Sbostic * Load the color map.
75752891Sbostic *
75852891Sbostic * Results:
75952891Sbostic * None.
76052891Sbostic *
76152891Sbostic * Side effects:
76252891Sbostic * The color map is loaded.
76352891Sbostic *
76452891Sbostic * ----------------------------------------------------------------------------
76552891Sbostic */
76652891Sbostic static void
cfbLoadColorMap(ptr)76756819Sralph cfbLoadColorMap(ptr)
76852891Sbostic ColorMap *ptr;
76952891Sbostic {
77056819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
77152891Sbostic
77252891Sbostic if (ptr->index > 256)
77352891Sbostic return;
77452891Sbostic
77552891Sbostic bt459_select_reg(regs, ptr->index);
77652891Sbostic
77752891Sbostic regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer();
77852891Sbostic regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer();
77952891Sbostic regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer();
78052891Sbostic }
78152891Sbostic
78252891Sbostic /*
78352891Sbostic * Video on/off state.
78452891Sbostic */
78556819Sralph static struct vstate {
78652891Sbostic u_char color0[3]; /* saved color map entry zero */
78752891Sbostic u_char off; /* TRUE if display is off */
78852891Sbostic } vstate;
78952891Sbostic
79052891Sbostic /*
79152891Sbostic * ----------------------------------------------------------------------------
79252891Sbostic *
79356819Sralph * bt459_video_on
79452891Sbostic *
79552891Sbostic * Enable the video display.
79652891Sbostic *
79752891Sbostic * Results:
79852891Sbostic * None.
79952891Sbostic *
80052891Sbostic * Side effects:
80152891Sbostic * The display is enabled.
80252891Sbostic *
80352891Sbostic * ----------------------------------------------------------------------------
80452891Sbostic */
80552891Sbostic static void
bt459_video_on()80656819Sralph bt459_video_on()
80752891Sbostic {
80856819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
80952891Sbostic
81052891Sbostic if (!vstate.off)
81152891Sbostic return;
81252891Sbostic
81352891Sbostic /* restore old color map entry zero */
81452891Sbostic bt459_select_reg(regs, 0);
81552891Sbostic regs->addr_cmap = vstate.color0[0];
81652891Sbostic MachEmptyWriteBuffer();
81752891Sbostic regs->addr_cmap = vstate.color0[1];
81852891Sbostic MachEmptyWriteBuffer();
81952891Sbostic regs->addr_cmap = vstate.color0[2];
82052891Sbostic MachEmptyWriteBuffer();
82152891Sbostic
82252891Sbostic /* enable normal display */
82352891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff);
82452891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0);
82552891Sbostic
82652891Sbostic vstate.off = 0;
82752891Sbostic }
82852891Sbostic
82952891Sbostic /*
83052891Sbostic * ----------------------------------------------------------------------------
83152891Sbostic *
83256819Sralph * bt459_video_off
83352891Sbostic *
83452891Sbostic * Disable the video display.
83552891Sbostic *
83652891Sbostic * Results:
83752891Sbostic * None.
83852891Sbostic *
83952891Sbostic * Side effects:
84052891Sbostic * The display is disabled.
84152891Sbostic *
84252891Sbostic * ----------------------------------------------------------------------------
84352891Sbostic */
84452891Sbostic static void
bt459_video_off()84556819Sralph bt459_video_off()
84652891Sbostic {
84756819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459);
84852891Sbostic
84952891Sbostic if (vstate.off)
85052891Sbostic return;
85152891Sbostic
85252891Sbostic /* save old color map entry zero */
85352891Sbostic bt459_select_reg(regs, 0);
85452891Sbostic vstate.color0[0] = regs->addr_cmap;
85552891Sbostic vstate.color0[1] = regs->addr_cmap;
85652891Sbostic vstate.color0[2] = regs->addr_cmap;
85752891Sbostic
85852891Sbostic /* set color map entry zero to zero */
85952891Sbostic bt459_select_reg(regs, 0);
86052891Sbostic regs->addr_cmap = 0;
86152891Sbostic MachEmptyWriteBuffer();
86252891Sbostic regs->addr_cmap = 0;
86352891Sbostic MachEmptyWriteBuffer();
86452891Sbostic regs->addr_cmap = 0;
86552891Sbostic MachEmptyWriteBuffer();
86652891Sbostic
86752891Sbostic /* disable display */
86852891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0);
86952891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0);
87052891Sbostic
87152891Sbostic vstate.off = 1;
87252891Sbostic }
87356819Sralph
87456819Sralph /*
87556819Sralph * cfb keyboard and mouse input. Just punt to the generic ones in fb.c
87656819Sralph */
87756819Sralph void
cfbKbdEvent(ch)87856819Sralph cfbKbdEvent(ch)
87956819Sralph int ch;
88056819Sralph {
88156819Sralph fbKbdEvent(ch, &cfbfb);
88256819Sralph }
88356819Sralph
88456819Sralph void
cfbMouseEvent(newRepPtr)88556819Sralph cfbMouseEvent(newRepPtr)
88656819Sralph MouseReport *newRepPtr;
88756819Sralph {
88856819Sralph fbMouseEvent(newRepPtr, &cfbfb);
88956819Sralph }
89056819Sralph
89156819Sralph void
cfbMouseButtons(newRepPtr)89256819Sralph cfbMouseButtons(newRepPtr)
89356819Sralph MouseReport *newRepPtr;
89456819Sralph {
89556819Sralph fbMouseButtons(newRepPtr, &cfbfb);
89656819Sralph }
89756819Sralph
89856819Sralph /*
89956819Sralph * Configure the mouse and keyboard based on machine type
90056819Sralph */
90156819Sralph static void
cfbConfigMouse()90256819Sralph cfbConfigMouse()
90356819Sralph {
90456819Sralph int s;
90556819Sralph
90656819Sralph s = spltty();
90756819Sralph switch (pmax_boardtype) {
90856819Sralph #if NDC > 0
90956819Sralph case DS_3MAX:
91056819Sralph dcDivertXInput = cfbKbdEvent;
91156819Sralph dcMouseEvent = cfbMouseEvent;
91256819Sralph dcMouseButtons = cfbMouseButtons;
91356819Sralph break;
91452891Sbostic #endif
91556819Sralph #if NSCC > 1
91656819Sralph case DS_3MIN:
91756819Sralph sccDivertXInput = cfbKbdEvent;
91856819Sralph sccMouseEvent = cfbMouseEvent;
91956819Sralph sccMouseButtons = cfbMouseButtons;
92056819Sralph break;
92156819Sralph #endif
92256819Sralph #if NDTOP > 0
92356819Sralph case DS_MAXINE:
92456819Sralph dtopDivertXInput = cfbKbdEvent;
92556819Sralph dtopMouseEvent = cfbMouseEvent;
92656819Sralph dtopMouseButtons = cfbMouseButtons;
92756819Sralph break;
92856819Sralph #endif
92956819Sralph default:
93056819Sralph printf("Can't configure mouse/keyboard\n");
93156819Sralph };
93256819Sralph splx(s);
93356819Sralph }
93456819Sralph
93556819Sralph /*
93656819Sralph * and deconfigure them
93756819Sralph */
93856819Sralph static void
cfbDeconfigMouse()93956819Sralph cfbDeconfigMouse()
94056819Sralph {
94156819Sralph int s;
94256819Sralph
94356819Sralph s = spltty();
94456819Sralph switch (pmax_boardtype) {
94556819Sralph #if NDC > 0
94656819Sralph case DS_3MAX:
94756819Sralph dcDivertXInput = (void (*)())0;
94856819Sralph dcMouseEvent = (void (*)())0;
94956819Sralph dcMouseButtons = (void (*)())0;
95056819Sralph break;
95156819Sralph #endif
95256819Sralph #if NSCC > 1
95356819Sralph case DS_3MIN:
95456819Sralph sccDivertXInput = (void (*)())0;
95556819Sralph sccMouseEvent = (void (*)())0;
95656819Sralph sccMouseButtons = (void (*)())0;
95756819Sralph break;
95856819Sralph #endif
95956819Sralph #if NDTOP > 0
96056819Sralph case DS_MAXINE:
96156819Sralph dtopDivertXInput = (void (*)())0;
96256819Sralph dtopMouseEvent = (void (*)())0;
96356819Sralph dtopMouseButtons = (void (*)())0;
96456819Sralph break;
96556819Sralph #endif
96656819Sralph default:
96756819Sralph printf("Can't deconfigure mouse/keyboard\n");
96856819Sralph };
96956819Sralph }
97056819Sralph #endif /* NCFB */
971