152891Sbostic /*- 2*63205Sbostic * Copyright (c) 1992, 1993 3*63205Sbostic * 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*63205Sbostic * @(#)cfb.c 8.1 (Berkeley) 06/10/93 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*/ 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*/ 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*/ 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*/ 20258974Sralph cfbioctl(dev, cmd, data, flag, p) 20352891Sbostic dev_t dev; 20452891Sbostic caddr_t data; 20558974Sralph struct proc *p; 20652891Sbostic { 20756819Sralph register struct pmax_fb *fp = &cfbfb; 20852959Sralph int s; 20952891Sbostic 21052891Sbostic switch (cmd) { 21152891Sbostic case QIOCGINFO: 21258974Sralph return (fbmmap(fp, dev, data, p)); 21352891Sbostic 21452891Sbostic case QIOCPMSTATE: 21552891Sbostic /* 21652891Sbostic * Set mouse state. 21752891Sbostic */ 21856819Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 21956819Sralph cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 22052891Sbostic break; 22152891Sbostic 22252891Sbostic case QIOCINIT: 22352891Sbostic /* 22452891Sbostic * Initialize the screen. 22552891Sbostic */ 22656819Sralph cfbScreenInit(); 22752891Sbostic break; 22852891Sbostic 22952891Sbostic case QIOCKPCMD: 23052891Sbostic { 23152891Sbostic pmKpCmd *kpCmdPtr; 23252891Sbostic unsigned char *cp; 23352891Sbostic 23452891Sbostic kpCmdPtr = (pmKpCmd *)data; 23552891Sbostic if (kpCmdPtr->nbytes == 0) 23652891Sbostic kpCmdPtr->cmd |= 0x80; 23756819Sralph if (!fp->GraphicsOpen) 23852891Sbostic kpCmdPtr->cmd |= 1; 23956819Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 24052891Sbostic cp = &kpCmdPtr->par[0]; 24152891Sbostic for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 24252891Sbostic if (kpCmdPtr->nbytes == 1) 24352891Sbostic *cp |= 0x80; 24456819Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 24552891Sbostic } 24658974Sralph break; 24752891Sbostic } 24852891Sbostic 24952891Sbostic case QIOCADDR: 25056819Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 25152891Sbostic break; 25252891Sbostic 25352891Sbostic case QIOWCURSOR: 25456819Sralph cfbLoadCursor((unsigned short *)data); 25552891Sbostic break; 25652891Sbostic 25752891Sbostic case QIOWCURSORCOLOR: 25856819Sralph cfbCursorColor((unsigned int *)data); 25952891Sbostic break; 26052891Sbostic 26152891Sbostic case QIOSETCMAP: 26256819Sralph cfbLoadColorMap((ColorMap *)data); 26352891Sbostic break; 26452891Sbostic 26552891Sbostic case QIOKERNLOOP: 26656819Sralph cfbConfigMouse(); 26752891Sbostic break; 26852891Sbostic 26952891Sbostic case QIOKERNUNLOOP: 27056819Sralph cfbDeconfigMouse(); 27152891Sbostic break; 27252891Sbostic 27352891Sbostic case QIOVIDEOON: 27456819Sralph cfbRestoreCursorColor(); 27556819Sralph bt459_video_on(); 27652891Sbostic break; 27752891Sbostic 27852891Sbostic case QIOVIDEOOFF: 27956819Sralph bt459_video_off(); 28052891Sbostic break; 28152891Sbostic 28252891Sbostic default: 28352891Sbostic printf("cfb0: Unknown ioctl command %x\n", cmd); 28452891Sbostic return (EINVAL); 28552891Sbostic } 28652891Sbostic return (0); 28752891Sbostic } 28852891Sbostic 28952891Sbostic cfbselect(dev, flag, p) 29052891Sbostic dev_t dev; 29152891Sbostic int flag; 29252891Sbostic struct proc *p; 29352891Sbostic { 29456819Sralph struct pmax_fb *fp = &cfbfb; 29552891Sbostic 29652891Sbostic switch (flag) { 29752891Sbostic case FREAD: 29856819Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 29952891Sbostic return (1); 30056819Sralph selrecord(p, &fp->selp); 30152891Sbostic break; 30252891Sbostic } 30352891Sbostic 30452891Sbostic return (0); 30552891Sbostic } 30652891Sbostic 30758974Sralph /* 30858974Sralph * Return the physical page number that corresponds to byte offset 'off'. 30958974Sralph */ 31058974Sralph /*ARGSUSED*/ 31158974Sralph cfbmap(dev, off, prot) 31258974Sralph dev_t dev; 31358974Sralph { 31458974Sralph int len; 31558974Sralph 31658974Sralph len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu)); 31758974Sralph if (off < len) 31858974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off); 31958974Sralph off -= len; 32058974Sralph if (off >= cfbfb.fr_size) 32158974Sralph return (-1); 32258974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off); 32358974Sralph } 32458974Sralph 32552891Sbostic static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 32652891Sbostic 32752891Sbostic /* 32856819Sralph * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM 32956819Sralph * defines a 64x64 cursor. If the bt459 does not map the cursor RAM 33056819Sralph * this way, this code is Screwed! 33152891Sbostic */ 33256819Sralph static void 33356819Sralph cfbLoadCursor(cursor) 33456819Sralph u_short *cursor; 33556819Sralph { 33659070Sralph #ifdef PMAX 33756819Sralph register int i, j, k, pos; 33856819Sralph register u_short ap, bp, out; 33952891Sbostic 34056819Sralph /* 34156819Sralph * Fill in the cursor sprite using the A and B planes, as provided 34256819Sralph * for the pmax. 34356819Sralph * XXX This will have to change when the X server knows that this 34456819Sralph * is not a pmax display. 34556819Sralph */ 34656819Sralph pos = 0; 34756819Sralph for (k = 0; k < 16; k++) { 34856819Sralph ap = *cursor; 34956819Sralph bp = *(cursor + 16); 35056819Sralph j = 0; 35156819Sralph while (j < 4) { 35256819Sralph out = 0; 35356819Sralph for (i = 0; i < 4; i++) { 35459824Sralph #ifndef CURSOR_EB 35556819Sralph out = (out << 2) | ((ap & 0x1) << 1) | 35656819Sralph (bp & 0x1); 35757234Sralph #else 35857234Sralph out = ((out >> 2) & 0x3f) | 35957234Sralph ((ap & 0x1) << 7) | 36057234Sralph ((bp & 0x1) << 6); 36157234Sralph #endif 36256819Sralph ap >>= 1; 36356819Sralph bp >>= 1; 36456819Sralph } 36556819Sralph bt459_set_cursor_ram(pos, out); 36656819Sralph pos++; 36756819Sralph j++; 36856819Sralph } 36956819Sralph while (j < 16) { 37056819Sralph bt459_set_cursor_ram(pos, 0); 37156819Sralph pos++; 37256819Sralph j++; 37356819Sralph } 37456819Sralph cursor++; 37556819Sralph } 37656819Sralph while (pos < 1024) { 37756819Sralph bt459_set_cursor_ram(pos, 0); 37856819Sralph pos++; 37956819Sralph } 38059070Sralph #endif /* PMAX */ 38156819Sralph } 38252891Sbostic 38352891Sbostic /* 38456819Sralph * Set a cursor ram value. 38556819Sralph */ 38656819Sralph static void 38756819Sralph bt459_set_cursor_ram(pos, val) 38856819Sralph int pos; 38956819Sralph register u_char val; 39056819Sralph { 39156819Sralph register bt459_regmap_t *regs = (bt459_regmap_t *) 39256819Sralph (cfbfb.fr_addr + CFB_OFFSET_BT459); 39356819Sralph register int cnt; 39456819Sralph u_char nval; 39556819Sralph 39656819Sralph cnt = 0; 39756819Sralph do { 39856819Sralph bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val); 39956819Sralph nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos); 40056819Sralph } while (val != nval && ++cnt < 10); 40156819Sralph } 40256819Sralph 40356819Sralph /* 40452891Sbostic * Generic register access 40552891Sbostic */ 40656819Sralph static void 40752891Sbostic bt459_select_reg(regs, regno) 40852891Sbostic bt459_regmap_t *regs; 40952891Sbostic { 41052891Sbostic regs->addr_lo = regno; 41152891Sbostic regs->addr_hi = regno >> 8; 41252891Sbostic MachEmptyWriteBuffer(); 41352891Sbostic } 41452891Sbostic 41556819Sralph static void 41652891Sbostic bt459_write_reg(regs, regno, val) 41752891Sbostic bt459_regmap_t *regs; 41852891Sbostic { 41952891Sbostic regs->addr_lo = regno; 42052891Sbostic regs->addr_hi = regno >> 8; 42152891Sbostic MachEmptyWriteBuffer(); 42252891Sbostic regs->addr_reg = val; 42352891Sbostic MachEmptyWriteBuffer(); 42452891Sbostic } 42552891Sbostic 42656819Sralph static u_char 42752891Sbostic bt459_read_reg(regs, regno) 42852891Sbostic bt459_regmap_t *regs; 42952891Sbostic { 43052891Sbostic regs->addr_lo = regno; 43152891Sbostic regs->addr_hi = regno >> 8; 43252891Sbostic MachEmptyWriteBuffer(); 43356819Sralph return (regs->addr_reg); 43452891Sbostic } 43552891Sbostic 43652891Sbostic /* 43756819Sralph * Initialization 43852891Sbostic */ 43956819Sralph int 44056819Sralph cfbinit(cp) 44156819Sralph char *cp; 44252891Sbostic { 44356819Sralph register bt459_regmap_t *regs; 44456819Sralph register struct pmax_fb *fp = &cfbfb; 44552891Sbostic 44652891Sbostic /* check for no frame buffer */ 44756819Sralph if (badaddr(cp, 4)) 44852891Sbostic return (0); 44952891Sbostic 45056819Sralph fp->isMono = 0; 45156819Sralph fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM); 45258974Sralph fp->fr_size = CFB_FB_SIZE; 45357234Sralph /* 45458974Sralph * Must be in Uncached space since the fbuaccess structure is 45558974Sralph * mapped into the user's address space uncached. 45657234Sralph */ 45757234Sralph fp->fbu = (struct fbuaccess *) 45857234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu)); 45956819Sralph fp->posCursor = cfbPosCursor; 46057234Sralph if (tb_kbdmouseconfig(fp)) 46156819Sralph return (0); 46252891Sbostic 46356819Sralph /* 46456819Sralph * Initialize the screen. 46556819Sralph */ 46656819Sralph regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459); 46756819Sralph 46852891Sbostic if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a) 46952891Sbostic return (0); 47052891Sbostic 47156819Sralph /* Reset the chip */ 47256819Sralph *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0; 47352891Sbostic DELAY(2000); /* ???? check right time on specs! ???? */ 47452891Sbostic 47552891Sbostic /* use 4:1 input mux */ 47652891Sbostic bt459_write_reg(regs, BT459_REG_CMD0, 0x40); 47752891Sbostic 47852891Sbostic /* no zooming, no panning */ 47952891Sbostic bt459_write_reg(regs, BT459_REG_CMD1, 0x00); 48052891Sbostic 48152891Sbostic /* 48252891Sbostic * signature test, X-windows cursor, no overlays, SYNC* PLL, 48352891Sbostic * normal RAM select, 7.5 IRE pedestal, do sync 48452891Sbostic */ 48559070Sralph #ifndef PMAX 48652891Sbostic bt459_write_reg(regs, BT459_REG_CMD2, 0xc2); 48759070Sralph #else /* PMAX */ 48859070Sralph bt459_write_reg(regs, BT459_REG_CMD2, 0xc0); 48959070Sralph #endif /* PMAX */ 49052891Sbostic 49152891Sbostic /* get all pixel bits */ 49252891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 49352891Sbostic 49452891Sbostic /* no blinking */ 49552891Sbostic bt459_write_reg(regs, BT459_REG_PBM, 0x00); 49652891Sbostic 49752891Sbostic /* no overlay */ 49852891Sbostic bt459_write_reg(regs, BT459_REG_ORM, 0x00); 49952891Sbostic 50052891Sbostic /* no overlay blink */ 50152891Sbostic bt459_write_reg(regs, BT459_REG_OBM, 0x00); 50252891Sbostic 50352891Sbostic /* no interleave, no underlay */ 50452891Sbostic bt459_write_reg(regs, BT459_REG_ILV, 0x00); 50552891Sbostic 50652891Sbostic /* normal operation, no signature analysis */ 50752891Sbostic bt459_write_reg(regs, BT459_REG_TEST, 0x00); 50852891Sbostic 50952891Sbostic /* 51052891Sbostic * no blinking, 1bit cross hair, XOR reg&crosshair, 51152891Sbostic * no crosshair on either plane 0 or 1, 51252891Sbostic * regular cursor on both planes. 51352891Sbostic */ 51452891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 51552891Sbostic 51652891Sbostic /* home cursor */ 51752891Sbostic bt459_write_reg(regs, BT459_REG_CXLO, 0x00); 51852891Sbostic bt459_write_reg(regs, BT459_REG_CXHI, 0x00); 51952891Sbostic bt459_write_reg(regs, BT459_REG_CYLO, 0x00); 52052891Sbostic bt459_write_reg(regs, BT459_REG_CYHI, 0x00); 52152891Sbostic 52252891Sbostic /* no crosshair window */ 52352891Sbostic bt459_write_reg(regs, BT459_REG_WXLO, 0x00); 52452891Sbostic bt459_write_reg(regs, BT459_REG_WXHI, 0x00); 52552891Sbostic bt459_write_reg(regs, BT459_REG_WYLO, 0x00); 52652891Sbostic bt459_write_reg(regs, BT459_REG_WYHI, 0x00); 52752891Sbostic bt459_write_reg(regs, BT459_REG_WWLO, 0x00); 52852891Sbostic bt459_write_reg(regs, BT459_REG_WWHI, 0x00); 52952891Sbostic bt459_write_reg(regs, BT459_REG_WHLO, 0x00); 53052891Sbostic bt459_write_reg(regs, BT459_REG_WHHI, 0x00); 53152891Sbostic 53252891Sbostic /* 53352891Sbostic * Initialize screen info. 53452891Sbostic */ 53556819Sralph fp->fbu->scrInfo.max_row = 56; 53656819Sralph fp->fbu->scrInfo.max_col = 80; 53756819Sralph fp->fbu->scrInfo.max_x = 1024; 53856819Sralph fp->fbu->scrInfo.max_y = 864; 53956819Sralph fp->fbu->scrInfo.max_cur_x = 1023; 54056819Sralph fp->fbu->scrInfo.max_cur_y = 863; 54156819Sralph fp->fbu->scrInfo.version = 11; 54256819Sralph fp->fbu->scrInfo.mthreshold = 4; 54356819Sralph fp->fbu->scrInfo.mscale = 2; 54456819Sralph fp->fbu->scrInfo.min_cur_x = 0; 54556819Sralph fp->fbu->scrInfo.min_cur_y = 0; 54656819Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 54756819Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 54856819Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 54956819Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 55056819Sralph fp->fbu->scrInfo.qe.tcNext = 0; 55152891Sbostic 55252891Sbostic /* 55352891Sbostic * Initialize the color map, the screen, and the mouse. 55452891Sbostic */ 55556819Sralph cfbInitColorMap(); 55656819Sralph cfbScreenInit(); 55756819Sralph fbScroll(fp); 55852891Sbostic 55956819Sralph fp->initialized = 1; 56056819Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 56156819Sralph cn_tab.cn_fb = fp; 56252891Sbostic return (1); 56352891Sbostic } 56452891Sbostic 56552891Sbostic /* 56652891Sbostic * ---------------------------------------------------------------------------- 56752891Sbostic * 56856819Sralph * cfbScreenInit -- 56952891Sbostic * 57052891Sbostic * Initialize the screen. 57152891Sbostic * 57252891Sbostic * Results: 57352891Sbostic * None. 57452891Sbostic * 57552891Sbostic * Side effects: 57652891Sbostic * The screen is initialized. 57752891Sbostic * 57852891Sbostic * ---------------------------------------------------------------------------- 57952891Sbostic */ 58052891Sbostic static void 58156819Sralph cfbScreenInit() 58252891Sbostic { 58356819Sralph register struct pmax_fb *fp = &cfbfb; 58452891Sbostic 58552891Sbostic /* 58652891Sbostic * Home the cursor. 58756819Sralph * We want an LSI terminal emulation. We want the graphics 58852891Sbostic * terminal to scroll from the bottom. So start at the bottom. 58952891Sbostic */ 59056819Sralph fp->row = 55; 59156819Sralph fp->col = 0; 59252891Sbostic 59352891Sbostic /* 59452891Sbostic * Load the cursor with the default values 59552891Sbostic * 59652891Sbostic */ 59756819Sralph cfbLoadCursor(defCursor); 59852891Sbostic } 59952891Sbostic 60052891Sbostic /* 60152891Sbostic * ---------------------------------------------------------------------------- 60252891Sbostic * 60352891Sbostic * RestoreCursorColor -- 60452891Sbostic * 60552891Sbostic * Routine to restore the color of the cursor. 60652891Sbostic * 60752891Sbostic * Results: 60852891Sbostic * None. 60952891Sbostic * 61052891Sbostic * Side effects: 61152891Sbostic * None. 61252891Sbostic * 61352891Sbostic * ---------------------------------------------------------------------------- 61452891Sbostic */ 61552891Sbostic static void 61656819Sralph cfbRestoreCursorColor() 61752891Sbostic { 61856819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 61952891Sbostic register int i; 62052891Sbostic 62159070Sralph #ifndef PMAX 62252891Sbostic bt459_select_reg(regs, BT459_REG_CCOLOR_2); 62352891Sbostic for (i = 0; i < 6; i++) { 62452891Sbostic regs->addr_reg = cursor_RGB[i]; 62552891Sbostic MachEmptyWriteBuffer(); 62652891Sbostic } 62759070Sralph #else /* PMAX */ 62859070Sralph bt459_select_reg(regs, BT459_REG_CCOLOR_1); 62959070Sralph for (i = 0; i < 3; i++) { 63059070Sralph regs->addr_reg = cursor_RGB[i]; 63159070Sralph MachEmptyWriteBuffer(); 63259070Sralph } 63359070Sralph bt459_select_reg(regs, BT459_REG_CCOLOR_3); 63459070Sralph for (i = 3; i < 6; i++) { 63559070Sralph regs->addr_reg = cursor_RGB[i]; 63659070Sralph MachEmptyWriteBuffer(); 63759070Sralph } 63859070Sralph #endif /* PMAX */ 63952891Sbostic } 64052891Sbostic 64152891Sbostic /* 64252891Sbostic * ---------------------------------------------------------------------------- 64352891Sbostic * 64452891Sbostic * CursorColor -- 64552891Sbostic * 64652891Sbostic * Set the color of the cursor. 64752891Sbostic * 64852891Sbostic * Results: 64952891Sbostic * None. 65052891Sbostic * 65152891Sbostic * Side effects: 65252891Sbostic * None. 65352891Sbostic * 65452891Sbostic * ---------------------------------------------------------------------------- 65552891Sbostic */ 65652891Sbostic static void 65756819Sralph cfbCursorColor(color) 65852891Sbostic unsigned int color[]; 65952891Sbostic { 66052891Sbostic register int i, j; 66152891Sbostic 66252891Sbostic for (i = 0; i < 6; i++) 66352891Sbostic cursor_RGB[i] = (u_char)(color[i] >> 8); 66452891Sbostic 66556819Sralph cfbRestoreCursorColor(); 66652891Sbostic } 66752891Sbostic 66852891Sbostic /* 66952891Sbostic *---------------------------------------------------------------------- 67052891Sbostic * 67152891Sbostic * PosCursor -- 67252891Sbostic * 67352891Sbostic * Postion the cursor. 67452891Sbostic * 67552891Sbostic * Results: 67652891Sbostic * None. 67752891Sbostic * 67852891Sbostic * Side effects: 67952891Sbostic * None. 68052891Sbostic * 68152891Sbostic *---------------------------------------------------------------------- 68252891Sbostic */ 68356819Sralph void 68456819Sralph cfbPosCursor(x, y) 68552891Sbostic register int x, y; 68652891Sbostic { 68756819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 68856819Sralph register struct pmax_fb *fp = &cfbfb; 68952891Sbostic 69056819Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 69156819Sralph y = fp->fbu->scrInfo.max_cur_y; 69256819Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 69356819Sralph x = fp->fbu->scrInfo.max_cur_x; 69456819Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 69556819Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 69652891Sbostic 69752891Sbostic x += 219; 69852891Sbostic y += 34; 69952891Sbostic 70052891Sbostic bt459_select_reg(regs, BT459_REG_CXLO); 70152891Sbostic regs->addr_reg = x; 70252891Sbostic MachEmptyWriteBuffer(); 70352891Sbostic regs->addr_reg = x >> 8; 70452891Sbostic MachEmptyWriteBuffer(); 70552891Sbostic regs->addr_reg = y; 70652891Sbostic MachEmptyWriteBuffer(); 70752891Sbostic regs->addr_reg = y >> 8; 70852891Sbostic MachEmptyWriteBuffer(); 70952891Sbostic } 71052891Sbostic 71152891Sbostic /* 71252891Sbostic * ---------------------------------------------------------------------------- 71352891Sbostic * 71452891Sbostic * InitColorMap -- 71552891Sbostic * 71652891Sbostic * Initialize the color map. 71752891Sbostic * 71852891Sbostic * Results: 71952891Sbostic * None. 72052891Sbostic * 72152891Sbostic * Side effects: 72252891Sbostic * The colormap is initialized appropriately. 72352891Sbostic * 72452891Sbostic * ---------------------------------------------------------------------------- 72552891Sbostic */ 72652891Sbostic static void 72756819Sralph cfbInitColorMap() 72852891Sbostic { 72956819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 73052891Sbostic register int i; 73152891Sbostic 73252891Sbostic bt459_select_reg(regs, 0); 73352891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 73452891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 73552891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 73652891Sbostic 73752891Sbostic for (i = 1; i < 256; i++) { 73852891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 73952891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 74052891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 74152891Sbostic } 74252891Sbostic 74352891Sbostic for (i = 0; i < 3; i++) { 74452891Sbostic cursor_RGB[i] = 0x00; 74552891Sbostic cursor_RGB[i + 3] = 0xff; 74652891Sbostic } 74756819Sralph cfbRestoreCursorColor(); 74852891Sbostic } 74952891Sbostic 75052891Sbostic /* 75152891Sbostic * ---------------------------------------------------------------------------- 75252891Sbostic * 75352891Sbostic * LoadColorMap -- 75452891Sbostic * 75552891Sbostic * Load the color map. 75652891Sbostic * 75752891Sbostic * Results: 75852891Sbostic * None. 75952891Sbostic * 76052891Sbostic * Side effects: 76152891Sbostic * The color map is loaded. 76252891Sbostic * 76352891Sbostic * ---------------------------------------------------------------------------- 76452891Sbostic */ 76552891Sbostic static void 76656819Sralph cfbLoadColorMap(ptr) 76752891Sbostic ColorMap *ptr; 76852891Sbostic { 76956819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 77052891Sbostic 77152891Sbostic if (ptr->index > 256) 77252891Sbostic return; 77352891Sbostic 77452891Sbostic bt459_select_reg(regs, ptr->index); 77552891Sbostic 77652891Sbostic regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer(); 77752891Sbostic regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer(); 77852891Sbostic regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer(); 77952891Sbostic } 78052891Sbostic 78152891Sbostic /* 78252891Sbostic * Video on/off state. 78352891Sbostic */ 78456819Sralph static struct vstate { 78552891Sbostic u_char color0[3]; /* saved color map entry zero */ 78652891Sbostic u_char off; /* TRUE if display is off */ 78752891Sbostic } vstate; 78852891Sbostic 78952891Sbostic /* 79052891Sbostic * ---------------------------------------------------------------------------- 79152891Sbostic * 79256819Sralph * bt459_video_on 79352891Sbostic * 79452891Sbostic * Enable the video display. 79552891Sbostic * 79652891Sbostic * Results: 79752891Sbostic * None. 79852891Sbostic * 79952891Sbostic * Side effects: 80052891Sbostic * The display is enabled. 80152891Sbostic * 80252891Sbostic * ---------------------------------------------------------------------------- 80352891Sbostic */ 80452891Sbostic static void 80556819Sralph bt459_video_on() 80652891Sbostic { 80756819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 80852891Sbostic 80952891Sbostic if (!vstate.off) 81052891Sbostic return; 81152891Sbostic 81252891Sbostic /* restore old color map entry zero */ 81352891Sbostic bt459_select_reg(regs, 0); 81452891Sbostic regs->addr_cmap = vstate.color0[0]; 81552891Sbostic MachEmptyWriteBuffer(); 81652891Sbostic regs->addr_cmap = vstate.color0[1]; 81752891Sbostic MachEmptyWriteBuffer(); 81852891Sbostic regs->addr_cmap = vstate.color0[2]; 81952891Sbostic MachEmptyWriteBuffer(); 82052891Sbostic 82152891Sbostic /* enable normal display */ 82252891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 82352891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 82452891Sbostic 82552891Sbostic vstate.off = 0; 82652891Sbostic } 82752891Sbostic 82852891Sbostic /* 82952891Sbostic * ---------------------------------------------------------------------------- 83052891Sbostic * 83156819Sralph * bt459_video_off 83252891Sbostic * 83352891Sbostic * Disable the video display. 83452891Sbostic * 83552891Sbostic * Results: 83652891Sbostic * None. 83752891Sbostic * 83852891Sbostic * Side effects: 83952891Sbostic * The display is disabled. 84052891Sbostic * 84152891Sbostic * ---------------------------------------------------------------------------- 84252891Sbostic */ 84352891Sbostic static void 84456819Sralph bt459_video_off() 84552891Sbostic { 84656819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 84752891Sbostic 84852891Sbostic if (vstate.off) 84952891Sbostic return; 85052891Sbostic 85152891Sbostic /* save old color map entry zero */ 85252891Sbostic bt459_select_reg(regs, 0); 85352891Sbostic vstate.color0[0] = regs->addr_cmap; 85452891Sbostic vstate.color0[1] = regs->addr_cmap; 85552891Sbostic vstate.color0[2] = regs->addr_cmap; 85652891Sbostic 85752891Sbostic /* set color map entry zero to zero */ 85852891Sbostic bt459_select_reg(regs, 0); 85952891Sbostic regs->addr_cmap = 0; 86052891Sbostic MachEmptyWriteBuffer(); 86152891Sbostic regs->addr_cmap = 0; 86252891Sbostic MachEmptyWriteBuffer(); 86352891Sbostic regs->addr_cmap = 0; 86452891Sbostic MachEmptyWriteBuffer(); 86552891Sbostic 86652891Sbostic /* disable display */ 86752891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0); 86852891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0); 86952891Sbostic 87052891Sbostic vstate.off = 1; 87152891Sbostic } 87256819Sralph 87356819Sralph /* 87456819Sralph * cfb keyboard and mouse input. Just punt to the generic ones in fb.c 87556819Sralph */ 87656819Sralph void 87756819Sralph cfbKbdEvent(ch) 87856819Sralph int ch; 87956819Sralph { 88056819Sralph fbKbdEvent(ch, &cfbfb); 88156819Sralph } 88256819Sralph 88356819Sralph void 88456819Sralph cfbMouseEvent(newRepPtr) 88556819Sralph MouseReport *newRepPtr; 88656819Sralph { 88756819Sralph fbMouseEvent(newRepPtr, &cfbfb); 88856819Sralph } 88956819Sralph 89056819Sralph void 89156819Sralph cfbMouseButtons(newRepPtr) 89256819Sralph MouseReport *newRepPtr; 89356819Sralph { 89456819Sralph fbMouseButtons(newRepPtr, &cfbfb); 89556819Sralph } 89656819Sralph 89756819Sralph /* 89856819Sralph * Configure the mouse and keyboard based on machine type 89956819Sralph */ 90056819Sralph static void 90156819Sralph cfbConfigMouse() 90256819Sralph { 90356819Sralph int s; 90456819Sralph 90556819Sralph s = spltty(); 90656819Sralph switch (pmax_boardtype) { 90756819Sralph #if NDC > 0 90856819Sralph case DS_3MAX: 90956819Sralph dcDivertXInput = cfbKbdEvent; 91056819Sralph dcMouseEvent = cfbMouseEvent; 91156819Sralph dcMouseButtons = cfbMouseButtons; 91256819Sralph break; 91352891Sbostic #endif 91456819Sralph #if NSCC > 1 91556819Sralph case DS_3MIN: 91656819Sralph sccDivertXInput = cfbKbdEvent; 91756819Sralph sccMouseEvent = cfbMouseEvent; 91856819Sralph sccMouseButtons = cfbMouseButtons; 91956819Sralph break; 92056819Sralph #endif 92156819Sralph #if NDTOP > 0 92256819Sralph case DS_MAXINE: 92356819Sralph dtopDivertXInput = cfbKbdEvent; 92456819Sralph dtopMouseEvent = cfbMouseEvent; 92556819Sralph dtopMouseButtons = cfbMouseButtons; 92656819Sralph break; 92756819Sralph #endif 92856819Sralph default: 92956819Sralph printf("Can't configure mouse/keyboard\n"); 93056819Sralph }; 93156819Sralph splx(s); 93256819Sralph } 93356819Sralph 93456819Sralph /* 93556819Sralph * and deconfigure them 93656819Sralph */ 93756819Sralph static void 93856819Sralph cfbDeconfigMouse() 93956819Sralph { 94056819Sralph int s; 94156819Sralph 94256819Sralph s = spltty(); 94356819Sralph switch (pmax_boardtype) { 94456819Sralph #if NDC > 0 94556819Sralph case DS_3MAX: 94656819Sralph dcDivertXInput = (void (*)())0; 94756819Sralph dcMouseEvent = (void (*)())0; 94856819Sralph dcMouseButtons = (void (*)())0; 94956819Sralph break; 95056819Sralph #endif 95156819Sralph #if NSCC > 1 95256819Sralph case DS_3MIN: 95356819Sralph sccDivertXInput = (void (*)())0; 95456819Sralph sccMouseEvent = (void (*)())0; 95556819Sralph sccMouseButtons = (void (*)())0; 95656819Sralph break; 95756819Sralph #endif 95856819Sralph #if NDTOP > 0 95956819Sralph case DS_MAXINE: 96056819Sralph dtopDivertXInput = (void (*)())0; 96156819Sralph dtopMouseEvent = (void (*)())0; 96256819Sralph dtopMouseButtons = (void (*)())0; 96356819Sralph break; 96456819Sralph #endif 96556819Sralph default: 96656819Sralph printf("Can't deconfigure mouse/keyboard\n"); 96756819Sralph }; 96856819Sralph } 96956819Sralph #endif /* NCFB */ 970