152891Sbostic /*- 252891Sbostic * Copyright (c) 1992 The Regents of the University of California. 352891Sbostic * 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*58974Sralph * @(#)cfb.c 7.7 (Berkeley) 04/05/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 8352891Sbostic /* 8452891Sbostic * These need to be mapped into user space. 8552891Sbostic */ 8656819Sralph struct fbuaccess cfbu; 8756819Sralph struct pmax_fb cfbfb; 8852891Sbostic 8952891Sbostic /* 9052891Sbostic * Forward references. 9152891Sbostic */ 9256819Sralph static void cfbScreenInit(); 9356819Sralph static void cfbLoadCursor(); 9456819Sralph static void cfbRestoreCursorColor(); 9556819Sralph static void cfbCursorColor(); 9656819Sralph void cfbPosCursor(); 9756819Sralph static void cfbInitColorMap(); 9856819Sralph static void cfbLoadColorMap(); 9956819Sralph static void bt459_set_cursor_ram(), bt459_video_on(), bt459_video_off(); 10056819Sralph static void bt459_select_reg(), bt459_write_reg(); 10156819Sralph static u_char bt459_read_reg(); 10256819Sralph static void cfbConfigMouse(), cfbDeconfigMouse(); 10352891Sbostic 10456819Sralph void cfbKbdEvent(), cfbMouseEvent(), cfbMouseButtons(); 10556819Sralph #if NDC > 0 10652891Sbostic extern void (*dcDivertXInput)(); 10752891Sbostic extern void (*dcMouseEvent)(); 10852891Sbostic extern void (*dcMouseButtons)(); 10956819Sralph #endif 11056819Sralph #if NSCC > 0 11156819Sralph extern void (*sccDivertXInput)(); 11256819Sralph extern void (*sccMouseEvent)(); 11356819Sralph extern void (*sccMouseButtons)(); 11456819Sralph #endif 11556819Sralph #if NDTOP > 0 11656819Sralph extern void (*dtopDivertXInput)(); 11756819Sralph extern void (*dtopMouseEvent)(); 11856819Sralph extern void (*dtopMouseButtons)(); 11956819Sralph #endif 12056819Sralph extern int pmax_boardtype; 12156819Sralph extern u_short defCursor[32]; 12256819Sralph extern struct consdev cn_tab; 12352891Sbostic 12452891Sbostic int cfbprobe(); 12552891Sbostic struct driver cfbdriver = { 12652891Sbostic "cfb", cfbprobe, 0, 0, 12752891Sbostic }; 12852891Sbostic 12956819Sralph #define CFB_OFFSET_VRAM 0x0 /* from module's base */ 13056819Sralph #define CFB_OFFSET_BT459 0x200000 /* Bt459 registers */ 13156819Sralph #define CFB_OFFSET_IREQ 0x300000 /* Interrupt req. control */ 13256819Sralph #define CFB_OFFSET_ROM 0x380000 /* Diagnostic ROM */ 13356819Sralph #define CFB_OFFSET_RESET 0x3c0000 /* Bt459 resets on writes */ 134*58974Sralph #define CFB_FB_SIZE 0x100000 /* frame buffer size */ 13556819Sralph 13652891Sbostic /* 13752891Sbostic * Test to see if device is present. 13852891Sbostic * Return true if found and initialized ok. 13952891Sbostic */ 14056819Sralph /*ARGSUSED*/ 14152891Sbostic cfbprobe(cp) 14252891Sbostic register struct pmax_ctlr *cp; 14352891Sbostic { 14456819Sralph register struct pmax_fb *fp = &cfbfb; 14552891Sbostic 14656819Sralph if (!fp->initialized && !cfbinit(cp->pmax_addr)) 14756819Sralph return (0); 14856819Sralph printf("cfb0 (color display)\n"); 14952891Sbostic return (1); 15052891Sbostic } 15152891Sbostic 15252891Sbostic /*ARGSUSED*/ 15352891Sbostic cfbopen(dev, flag) 15452891Sbostic dev_t dev; 15552891Sbostic int flag; 15652891Sbostic { 15756819Sralph register struct pmax_fb *fp = &cfbfb; 15856819Sralph int s; 15952891Sbostic 16056819Sralph if (!fp->initialized) 16152891Sbostic return (ENXIO); 16256819Sralph if (fp->GraphicsOpen) 16352891Sbostic return (EBUSY); 16452891Sbostic 16556819Sralph fp->GraphicsOpen = 1; 16656819Sralph cfbInitColorMap(); 16752891Sbostic /* 16852891Sbostic * Set up event queue for later 16952891Sbostic */ 17056819Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 17156819Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 17256819Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 17356819Sralph fp->fbu->scrInfo.qe.tcNext = 0; 17456819Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 17556819Sralph cfbConfigMouse(); 17652891Sbostic return (0); 17752891Sbostic } 17852891Sbostic 17952891Sbostic /*ARGSUSED*/ 18052891Sbostic cfbclose(dev, flag) 18152891Sbostic dev_t dev; 18252891Sbostic int flag; 18352891Sbostic { 18456819Sralph register struct pmax_fb *fp = &cfbfb; 18552959Sralph int s; 18652891Sbostic 18756819Sralph if (!fp->GraphicsOpen) 18852891Sbostic return (EBADF); 18952891Sbostic 19056819Sralph fp->GraphicsOpen = 0; 19156819Sralph cfbInitColorMap(); 19256819Sralph cfbDeconfigMouse(); 19356819Sralph cfbScreenInit(); 19456819Sralph bzero((caddr_t)fp->fr_addr, 1024 * 864); 19556819Sralph cfbPosCursor(fp->col * 8, fp->row * 15); 19652891Sbostic return (0); 19752891Sbostic } 19852891Sbostic 19952891Sbostic /*ARGSUSED*/ 200*58974Sralph cfbioctl(dev, cmd, data, flag, p) 20152891Sbostic dev_t dev; 20252891Sbostic caddr_t data; 203*58974Sralph struct proc *p; 20452891Sbostic { 20556819Sralph register struct pmax_fb *fp = &cfbfb; 20652959Sralph int s; 20752891Sbostic 20852891Sbostic switch (cmd) { 20952891Sbostic case QIOCGINFO: 210*58974Sralph return (fbmmap(fp, dev, data, p)); 21152891Sbostic 21252891Sbostic case QIOCPMSTATE: 21352891Sbostic /* 21452891Sbostic * Set mouse state. 21552891Sbostic */ 21656819Sralph fp->fbu->scrInfo.mouse = *(pmCursor *)data; 21756819Sralph cfbPosCursor(fp->fbu->scrInfo.mouse.x, fp->fbu->scrInfo.mouse.y); 21852891Sbostic break; 21952891Sbostic 22052891Sbostic case QIOCINIT: 22152891Sbostic /* 22252891Sbostic * Initialize the screen. 22352891Sbostic */ 22456819Sralph cfbScreenInit(); 22552891Sbostic break; 22652891Sbostic 22752891Sbostic case QIOCKPCMD: 22852891Sbostic { 22952891Sbostic pmKpCmd *kpCmdPtr; 23052891Sbostic unsigned char *cp; 23152891Sbostic 23252891Sbostic kpCmdPtr = (pmKpCmd *)data; 23352891Sbostic if (kpCmdPtr->nbytes == 0) 23452891Sbostic kpCmdPtr->cmd |= 0x80; 23556819Sralph if (!fp->GraphicsOpen) 23652891Sbostic kpCmdPtr->cmd |= 1; 23756819Sralph (*fp->KBDPutc)(fp->kbddev, (int)kpCmdPtr->cmd); 23852891Sbostic cp = &kpCmdPtr->par[0]; 23952891Sbostic for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 24052891Sbostic if (kpCmdPtr->nbytes == 1) 24152891Sbostic *cp |= 0x80; 24256819Sralph (*fp->KBDPutc)(fp->kbddev, (int)*cp); 24352891Sbostic } 244*58974Sralph break; 24552891Sbostic } 24652891Sbostic 24752891Sbostic case QIOCADDR: 24856819Sralph *(PM_Info **)data = &fp->fbu->scrInfo; 24952891Sbostic break; 25052891Sbostic 25152891Sbostic case QIOWCURSOR: 25256819Sralph cfbLoadCursor((unsigned short *)data); 25352891Sbostic break; 25452891Sbostic 25552891Sbostic case QIOWCURSORCOLOR: 25656819Sralph cfbCursorColor((unsigned int *)data); 25752891Sbostic break; 25852891Sbostic 25952891Sbostic case QIOSETCMAP: 26056819Sralph cfbLoadColorMap((ColorMap *)data); 26152891Sbostic break; 26252891Sbostic 26352891Sbostic case QIOKERNLOOP: 26456819Sralph cfbConfigMouse(); 26552891Sbostic break; 26652891Sbostic 26752891Sbostic case QIOKERNUNLOOP: 26856819Sralph cfbDeconfigMouse(); 26952891Sbostic break; 27052891Sbostic 27152891Sbostic case QIOVIDEOON: 27256819Sralph cfbRestoreCursorColor(); 27356819Sralph bt459_video_on(); 27452891Sbostic break; 27552891Sbostic 27652891Sbostic case QIOVIDEOOFF: 27756819Sralph bt459_video_off(); 27852891Sbostic break; 27952891Sbostic 28052891Sbostic default: 28152891Sbostic printf("cfb0: Unknown ioctl command %x\n", cmd); 28252891Sbostic return (EINVAL); 28352891Sbostic } 28452891Sbostic return (0); 28552891Sbostic } 28652891Sbostic 28752891Sbostic cfbselect(dev, flag, p) 28852891Sbostic dev_t dev; 28952891Sbostic int flag; 29052891Sbostic struct proc *p; 29152891Sbostic { 29256819Sralph struct pmax_fb *fp = &cfbfb; 29352891Sbostic 29452891Sbostic switch (flag) { 29552891Sbostic case FREAD: 29656819Sralph if (fp->fbu->scrInfo.qe.eHead != fp->fbu->scrInfo.qe.eTail) 29752891Sbostic return (1); 29856819Sralph selrecord(p, &fp->selp); 29952891Sbostic break; 30052891Sbostic } 30152891Sbostic 30252891Sbostic return (0); 30352891Sbostic } 30452891Sbostic 305*58974Sralph /* 306*58974Sralph * Return the physical page number that corresponds to byte offset 'off'. 307*58974Sralph */ 308*58974Sralph /*ARGSUSED*/ 309*58974Sralph cfbmap(dev, off, prot) 310*58974Sralph dev_t dev; 311*58974Sralph { 312*58974Sralph int len; 313*58974Sralph 314*58974Sralph len = pmax_round_page(((vm_offset_t)&cfbu & PGOFSET) + sizeof(cfbu)); 315*58974Sralph if (off < len) 316*58974Sralph return pmax_btop(MACH_CACHED_TO_PHYS(&cfbu) + off); 317*58974Sralph off -= len; 318*58974Sralph if (off >= cfbfb.fr_size) 319*58974Sralph return (-1); 320*58974Sralph return pmax_btop(MACH_UNCACHED_TO_PHYS(cfbfb.fr_addr) + off); 321*58974Sralph } 322*58974Sralph 32352891Sbostic static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 32452891Sbostic 32552891Sbostic /* 32656819Sralph * XXX This assumes 2bits/cursor pixel so that the 1Kbyte cursor RAM 32756819Sralph * defines a 64x64 cursor. If the bt459 does not map the cursor RAM 32856819Sralph * this way, this code is Screwed! 32952891Sbostic */ 33056819Sralph static void 33156819Sralph cfbLoadCursor(cursor) 33256819Sralph u_short *cursor; 33356819Sralph { 33456819Sralph register int i, j, k, pos; 33556819Sralph register u_short ap, bp, out; 33652891Sbostic 33756819Sralph /* 33856819Sralph * Fill in the cursor sprite using the A and B planes, as provided 33956819Sralph * for the pmax. 34056819Sralph * XXX This will have to change when the X server knows that this 34156819Sralph * is not a pmax display. 34256819Sralph */ 34356819Sralph pos = 0; 34456819Sralph for (k = 0; k < 16; k++) { 34556819Sralph ap = *cursor; 34656819Sralph bp = *(cursor + 16); 34756819Sralph j = 0; 34856819Sralph while (j < 4) { 34956819Sralph out = 0; 35056819Sralph for (i = 0; i < 4; i++) { 35157234Sralph #ifdef CURSOR_EL 35256819Sralph out = (out << 2) | ((ap & 0x1) << 1) | 35356819Sralph (bp & 0x1); 35457234Sralph #else 35557234Sralph out = ((out >> 2) & 0x3f) | 35657234Sralph ((ap & 0x1) << 7) | 35757234Sralph ((bp & 0x1) << 6); 35857234Sralph #endif 35956819Sralph ap >>= 1; 36056819Sralph bp >>= 1; 36156819Sralph } 36256819Sralph bt459_set_cursor_ram(pos, out); 36356819Sralph pos++; 36456819Sralph j++; 36556819Sralph } 36656819Sralph while (j < 16) { 36756819Sralph bt459_set_cursor_ram(pos, 0); 36856819Sralph pos++; 36956819Sralph j++; 37056819Sralph } 37156819Sralph cursor++; 37256819Sralph } 37356819Sralph while (pos < 1024) { 37456819Sralph bt459_set_cursor_ram(pos, 0); 37556819Sralph pos++; 37656819Sralph } 37756819Sralph } 37852891Sbostic 37952891Sbostic /* 38056819Sralph * Set a cursor ram value. 38156819Sralph */ 38256819Sralph static void 38356819Sralph bt459_set_cursor_ram(pos, val) 38456819Sralph int pos; 38556819Sralph register u_char val; 38656819Sralph { 38756819Sralph register bt459_regmap_t *regs = (bt459_regmap_t *) 38856819Sralph (cfbfb.fr_addr + CFB_OFFSET_BT459); 38956819Sralph register int cnt; 39056819Sralph u_char nval; 39156819Sralph 39256819Sralph cnt = 0; 39356819Sralph do { 39456819Sralph bt459_write_reg(regs, BT459_REG_CRAM_BASE + pos, val); 39556819Sralph nval = bt459_read_reg(regs, BT459_REG_CRAM_BASE + pos); 39656819Sralph } while (val != nval && ++cnt < 10); 39756819Sralph } 39856819Sralph 39956819Sralph /* 40052891Sbostic * Generic register access 40152891Sbostic */ 40256819Sralph static void 40352891Sbostic bt459_select_reg(regs, regno) 40452891Sbostic bt459_regmap_t *regs; 40552891Sbostic { 40652891Sbostic regs->addr_lo = regno; 40752891Sbostic regs->addr_hi = regno >> 8; 40852891Sbostic MachEmptyWriteBuffer(); 40952891Sbostic } 41052891Sbostic 41156819Sralph static void 41252891Sbostic bt459_write_reg(regs, regno, val) 41352891Sbostic bt459_regmap_t *regs; 41452891Sbostic { 41552891Sbostic regs->addr_lo = regno; 41652891Sbostic regs->addr_hi = regno >> 8; 41752891Sbostic MachEmptyWriteBuffer(); 41852891Sbostic regs->addr_reg = val; 41952891Sbostic MachEmptyWriteBuffer(); 42052891Sbostic } 42152891Sbostic 42256819Sralph static u_char 42352891Sbostic bt459_read_reg(regs, regno) 42452891Sbostic bt459_regmap_t *regs; 42552891Sbostic { 42652891Sbostic regs->addr_lo = regno; 42752891Sbostic regs->addr_hi = regno >> 8; 42852891Sbostic MachEmptyWriteBuffer(); 42956819Sralph return (regs->addr_reg); 43052891Sbostic } 43152891Sbostic 43252891Sbostic /* 43356819Sralph * Initialization 43452891Sbostic */ 43556819Sralph int 43656819Sralph cfbinit(cp) 43756819Sralph char *cp; 43852891Sbostic { 43956819Sralph register bt459_regmap_t *regs; 44056819Sralph register struct pmax_fb *fp = &cfbfb; 44152891Sbostic 44252891Sbostic /* check for no frame buffer */ 44356819Sralph if (badaddr(cp, 4)) 44452891Sbostic return (0); 44552891Sbostic 44656819Sralph fp->isMono = 0; 44756819Sralph fp->fr_addr = (char *)(cp + CFB_OFFSET_VRAM); 448*58974Sralph fp->fr_size = CFB_FB_SIZE; 44957234Sralph /* 450*58974Sralph * Must be in Uncached space since the fbuaccess structure is 451*58974Sralph * mapped into the user's address space uncached. 45257234Sralph */ 45357234Sralph fp->fbu = (struct fbuaccess *) 45457234Sralph MACH_PHYS_TO_UNCACHED(MACH_CACHED_TO_PHYS(&cfbu)); 45556819Sralph fp->posCursor = cfbPosCursor; 45657234Sralph if (tb_kbdmouseconfig(fp)) 45756819Sralph return (0); 45852891Sbostic 45956819Sralph /* 46056819Sralph * Initialize the screen. 46156819Sralph */ 46256819Sralph regs = (bt459_regmap_t *)(fp->fr_addr + CFB_OFFSET_BT459); 46356819Sralph 46452891Sbostic if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a) 46552891Sbostic return (0); 46652891Sbostic 46756819Sralph /* Reset the chip */ 46856819Sralph *(volatile int *)(fp->fr_addr + CFB_OFFSET_RESET) = 0; 46952891Sbostic DELAY(2000); /* ???? check right time on specs! ???? */ 47052891Sbostic 47152891Sbostic /* use 4:1 input mux */ 47252891Sbostic bt459_write_reg(regs, BT459_REG_CMD0, 0x40); 47352891Sbostic 47452891Sbostic /* no zooming, no panning */ 47552891Sbostic bt459_write_reg(regs, BT459_REG_CMD1, 0x00); 47652891Sbostic 47752891Sbostic /* 47852891Sbostic * signature test, X-windows cursor, no overlays, SYNC* PLL, 47952891Sbostic * normal RAM select, 7.5 IRE pedestal, do sync 48052891Sbostic */ 48152891Sbostic bt459_write_reg(regs, BT459_REG_CMD2, 0xc2); 48252891Sbostic 48352891Sbostic /* get all pixel bits */ 48452891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 48552891Sbostic 48652891Sbostic /* no blinking */ 48752891Sbostic bt459_write_reg(regs, BT459_REG_PBM, 0x00); 48852891Sbostic 48952891Sbostic /* no overlay */ 49052891Sbostic bt459_write_reg(regs, BT459_REG_ORM, 0x00); 49152891Sbostic 49252891Sbostic /* no overlay blink */ 49352891Sbostic bt459_write_reg(regs, BT459_REG_OBM, 0x00); 49452891Sbostic 49552891Sbostic /* no interleave, no underlay */ 49652891Sbostic bt459_write_reg(regs, BT459_REG_ILV, 0x00); 49752891Sbostic 49852891Sbostic /* normal operation, no signature analysis */ 49952891Sbostic bt459_write_reg(regs, BT459_REG_TEST, 0x00); 50052891Sbostic 50152891Sbostic /* 50252891Sbostic * no blinking, 1bit cross hair, XOR reg&crosshair, 50352891Sbostic * no crosshair on either plane 0 or 1, 50452891Sbostic * regular cursor on both planes. 50552891Sbostic */ 50652891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 50752891Sbostic 50852891Sbostic /* home cursor */ 50952891Sbostic bt459_write_reg(regs, BT459_REG_CXLO, 0x00); 51052891Sbostic bt459_write_reg(regs, BT459_REG_CXHI, 0x00); 51152891Sbostic bt459_write_reg(regs, BT459_REG_CYLO, 0x00); 51252891Sbostic bt459_write_reg(regs, BT459_REG_CYHI, 0x00); 51352891Sbostic 51452891Sbostic /* no crosshair window */ 51552891Sbostic bt459_write_reg(regs, BT459_REG_WXLO, 0x00); 51652891Sbostic bt459_write_reg(regs, BT459_REG_WXHI, 0x00); 51752891Sbostic bt459_write_reg(regs, BT459_REG_WYLO, 0x00); 51852891Sbostic bt459_write_reg(regs, BT459_REG_WYHI, 0x00); 51952891Sbostic bt459_write_reg(regs, BT459_REG_WWLO, 0x00); 52052891Sbostic bt459_write_reg(regs, BT459_REG_WWHI, 0x00); 52152891Sbostic bt459_write_reg(regs, BT459_REG_WHLO, 0x00); 52252891Sbostic bt459_write_reg(regs, BT459_REG_WHHI, 0x00); 52352891Sbostic 52452891Sbostic /* 52552891Sbostic * Initialize screen info. 52652891Sbostic */ 52756819Sralph fp->fbu->scrInfo.max_row = 56; 52856819Sralph fp->fbu->scrInfo.max_col = 80; 52956819Sralph fp->fbu->scrInfo.max_x = 1024; 53056819Sralph fp->fbu->scrInfo.max_y = 864; 53156819Sralph fp->fbu->scrInfo.max_cur_x = 1023; 53256819Sralph fp->fbu->scrInfo.max_cur_y = 863; 53356819Sralph fp->fbu->scrInfo.version = 11; 53456819Sralph fp->fbu->scrInfo.mthreshold = 4; 53556819Sralph fp->fbu->scrInfo.mscale = 2; 53656819Sralph fp->fbu->scrInfo.min_cur_x = 0; 53756819Sralph fp->fbu->scrInfo.min_cur_y = 0; 53856819Sralph fp->fbu->scrInfo.qe.timestamp_ms = TO_MS(time); 53956819Sralph fp->fbu->scrInfo.qe.eSize = PM_MAXEVQ; 54056819Sralph fp->fbu->scrInfo.qe.eHead = fp->fbu->scrInfo.qe.eTail = 0; 54156819Sralph fp->fbu->scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 54256819Sralph fp->fbu->scrInfo.qe.tcNext = 0; 54352891Sbostic 54452891Sbostic /* 54552891Sbostic * Initialize the color map, the screen, and the mouse. 54652891Sbostic */ 54756819Sralph cfbInitColorMap(); 54856819Sralph cfbScreenInit(); 54956819Sralph fbScroll(fp); 55052891Sbostic 55156819Sralph fp->initialized = 1; 55256819Sralph if (cn_tab.cn_fb == (struct pmax_fb *)0) 55356819Sralph cn_tab.cn_fb = fp; 55452891Sbostic return (1); 55552891Sbostic } 55652891Sbostic 55752891Sbostic /* 55852891Sbostic * ---------------------------------------------------------------------------- 55952891Sbostic * 56056819Sralph * cfbScreenInit -- 56152891Sbostic * 56252891Sbostic * Initialize the screen. 56352891Sbostic * 56452891Sbostic * Results: 56552891Sbostic * None. 56652891Sbostic * 56752891Sbostic * Side effects: 56852891Sbostic * The screen is initialized. 56952891Sbostic * 57052891Sbostic * ---------------------------------------------------------------------------- 57152891Sbostic */ 57252891Sbostic static void 57356819Sralph cfbScreenInit() 57452891Sbostic { 57556819Sralph register struct pmax_fb *fp = &cfbfb; 57652891Sbostic 57752891Sbostic /* 57852891Sbostic * Home the cursor. 57956819Sralph * We want an LSI terminal emulation. We want the graphics 58052891Sbostic * terminal to scroll from the bottom. So start at the bottom. 58152891Sbostic */ 58256819Sralph fp->row = 55; 58356819Sralph fp->col = 0; 58452891Sbostic 58552891Sbostic /* 58652891Sbostic * Load the cursor with the default values 58752891Sbostic * 58852891Sbostic */ 58956819Sralph cfbLoadCursor(defCursor); 59052891Sbostic } 59152891Sbostic 59252891Sbostic /* 59352891Sbostic * ---------------------------------------------------------------------------- 59452891Sbostic * 59552891Sbostic * RestoreCursorColor -- 59652891Sbostic * 59752891Sbostic * Routine to restore the color of the cursor. 59852891Sbostic * 59952891Sbostic * Results: 60052891Sbostic * None. 60152891Sbostic * 60252891Sbostic * Side effects: 60352891Sbostic * None. 60452891Sbostic * 60552891Sbostic * ---------------------------------------------------------------------------- 60652891Sbostic */ 60752891Sbostic static void 60856819Sralph cfbRestoreCursorColor() 60952891Sbostic { 61056819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 61152891Sbostic register int i; 61252891Sbostic 61352891Sbostic bt459_select_reg(regs, BT459_REG_CCOLOR_2); 61452891Sbostic for (i = 0; i < 6; i++) { 61552891Sbostic regs->addr_reg = cursor_RGB[i]; 61652891Sbostic MachEmptyWriteBuffer(); 61752891Sbostic } 61852891Sbostic } 61952891Sbostic 62052891Sbostic /* 62152891Sbostic * ---------------------------------------------------------------------------- 62252891Sbostic * 62352891Sbostic * CursorColor -- 62452891Sbostic * 62552891Sbostic * Set the color of the cursor. 62652891Sbostic * 62752891Sbostic * Results: 62852891Sbostic * None. 62952891Sbostic * 63052891Sbostic * Side effects: 63152891Sbostic * None. 63252891Sbostic * 63352891Sbostic * ---------------------------------------------------------------------------- 63452891Sbostic */ 63552891Sbostic static void 63656819Sralph cfbCursorColor(color) 63752891Sbostic unsigned int color[]; 63852891Sbostic { 63952891Sbostic register int i, j; 64052891Sbostic 64152891Sbostic for (i = 0; i < 6; i++) 64252891Sbostic cursor_RGB[i] = (u_char)(color[i] >> 8); 64352891Sbostic 64456819Sralph cfbRestoreCursorColor(); 64552891Sbostic } 64652891Sbostic 64752891Sbostic /* 64852891Sbostic *---------------------------------------------------------------------- 64952891Sbostic * 65052891Sbostic * PosCursor -- 65152891Sbostic * 65252891Sbostic * Postion the cursor. 65352891Sbostic * 65452891Sbostic * Results: 65552891Sbostic * None. 65652891Sbostic * 65752891Sbostic * Side effects: 65852891Sbostic * None. 65952891Sbostic * 66052891Sbostic *---------------------------------------------------------------------- 66152891Sbostic */ 66256819Sralph void 66356819Sralph cfbPosCursor(x, y) 66452891Sbostic register int x, y; 66552891Sbostic { 66656819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 66756819Sralph register struct pmax_fb *fp = &cfbfb; 66852891Sbostic 66956819Sralph if (y < fp->fbu->scrInfo.min_cur_y || y > fp->fbu->scrInfo.max_cur_y) 67056819Sralph y = fp->fbu->scrInfo.max_cur_y; 67156819Sralph if (x < fp->fbu->scrInfo.min_cur_x || x > fp->fbu->scrInfo.max_cur_x) 67256819Sralph x = fp->fbu->scrInfo.max_cur_x; 67356819Sralph fp->fbu->scrInfo.cursor.x = x; /* keep track of real cursor */ 67456819Sralph fp->fbu->scrInfo.cursor.y = y; /* position, indep. of mouse */ 67552891Sbostic 67652891Sbostic x += 219; 67752891Sbostic y += 34; 67852891Sbostic 67952891Sbostic bt459_select_reg(regs, BT459_REG_CXLO); 68052891Sbostic regs->addr_reg = x; 68152891Sbostic MachEmptyWriteBuffer(); 68252891Sbostic regs->addr_reg = x >> 8; 68352891Sbostic MachEmptyWriteBuffer(); 68452891Sbostic regs->addr_reg = y; 68552891Sbostic MachEmptyWriteBuffer(); 68652891Sbostic regs->addr_reg = y >> 8; 68752891Sbostic MachEmptyWriteBuffer(); 68852891Sbostic } 68952891Sbostic 69052891Sbostic /* 69152891Sbostic * ---------------------------------------------------------------------------- 69252891Sbostic * 69352891Sbostic * InitColorMap -- 69452891Sbostic * 69552891Sbostic * Initialize the color map. 69652891Sbostic * 69752891Sbostic * Results: 69852891Sbostic * None. 69952891Sbostic * 70052891Sbostic * Side effects: 70152891Sbostic * The colormap is initialized appropriately. 70252891Sbostic * 70352891Sbostic * ---------------------------------------------------------------------------- 70452891Sbostic */ 70552891Sbostic static void 70656819Sralph cfbInitColorMap() 70752891Sbostic { 70856819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 70952891Sbostic register int i; 71052891Sbostic 71152891Sbostic bt459_select_reg(regs, 0); 71252891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 71352891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 71452891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 71552891Sbostic 71652891Sbostic for (i = 1; i < 256; i++) { 71752891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 71852891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 71952891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 72052891Sbostic } 72152891Sbostic 72252891Sbostic for (i = 0; i < 3; i++) { 72352891Sbostic cursor_RGB[i] = 0x00; 72452891Sbostic cursor_RGB[i + 3] = 0xff; 72552891Sbostic } 72656819Sralph cfbRestoreCursorColor(); 72752891Sbostic } 72852891Sbostic 72952891Sbostic /* 73052891Sbostic * ---------------------------------------------------------------------------- 73152891Sbostic * 73252891Sbostic * LoadColorMap -- 73352891Sbostic * 73452891Sbostic * Load the color map. 73552891Sbostic * 73652891Sbostic * Results: 73752891Sbostic * None. 73852891Sbostic * 73952891Sbostic * Side effects: 74052891Sbostic * The color map is loaded. 74152891Sbostic * 74252891Sbostic * ---------------------------------------------------------------------------- 74352891Sbostic */ 74452891Sbostic static void 74556819Sralph cfbLoadColorMap(ptr) 74652891Sbostic ColorMap *ptr; 74752891Sbostic { 74856819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 74952891Sbostic 75052891Sbostic if (ptr->index > 256) 75152891Sbostic return; 75252891Sbostic 75352891Sbostic bt459_select_reg(regs, ptr->index); 75452891Sbostic 75552891Sbostic regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer(); 75652891Sbostic regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer(); 75752891Sbostic regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer(); 75852891Sbostic } 75952891Sbostic 76052891Sbostic /* 76152891Sbostic * Video on/off state. 76252891Sbostic */ 76356819Sralph static struct vstate { 76452891Sbostic u_char color0[3]; /* saved color map entry zero */ 76552891Sbostic u_char off; /* TRUE if display is off */ 76652891Sbostic } vstate; 76752891Sbostic 76852891Sbostic /* 76952891Sbostic * ---------------------------------------------------------------------------- 77052891Sbostic * 77156819Sralph * bt459_video_on 77252891Sbostic * 77352891Sbostic * Enable the video display. 77452891Sbostic * 77552891Sbostic * Results: 77652891Sbostic * None. 77752891Sbostic * 77852891Sbostic * Side effects: 77952891Sbostic * The display is enabled. 78052891Sbostic * 78152891Sbostic * ---------------------------------------------------------------------------- 78252891Sbostic */ 78352891Sbostic static void 78456819Sralph bt459_video_on() 78552891Sbostic { 78656819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 78752891Sbostic 78852891Sbostic if (!vstate.off) 78952891Sbostic return; 79052891Sbostic 79152891Sbostic /* restore old color map entry zero */ 79252891Sbostic bt459_select_reg(regs, 0); 79352891Sbostic regs->addr_cmap = vstate.color0[0]; 79452891Sbostic MachEmptyWriteBuffer(); 79552891Sbostic regs->addr_cmap = vstate.color0[1]; 79652891Sbostic MachEmptyWriteBuffer(); 79752891Sbostic regs->addr_cmap = vstate.color0[2]; 79852891Sbostic MachEmptyWriteBuffer(); 79952891Sbostic 80052891Sbostic /* enable normal display */ 80152891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 80252891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 80352891Sbostic 80452891Sbostic vstate.off = 0; 80552891Sbostic } 80652891Sbostic 80752891Sbostic /* 80852891Sbostic * ---------------------------------------------------------------------------- 80952891Sbostic * 81056819Sralph * bt459_video_off 81152891Sbostic * 81252891Sbostic * Disable the video display. 81352891Sbostic * 81452891Sbostic * Results: 81552891Sbostic * None. 81652891Sbostic * 81752891Sbostic * Side effects: 81852891Sbostic * The display is disabled. 81952891Sbostic * 82052891Sbostic * ---------------------------------------------------------------------------- 82152891Sbostic */ 82252891Sbostic static void 82356819Sralph bt459_video_off() 82452891Sbostic { 82556819Sralph bt459_regmap_t *regs = (bt459_regmap_t *)(cfbfb.fr_addr + CFB_OFFSET_BT459); 82652891Sbostic 82752891Sbostic if (vstate.off) 82852891Sbostic return; 82952891Sbostic 83052891Sbostic /* save old color map entry zero */ 83152891Sbostic bt459_select_reg(regs, 0); 83252891Sbostic vstate.color0[0] = regs->addr_cmap; 83352891Sbostic vstate.color0[1] = regs->addr_cmap; 83452891Sbostic vstate.color0[2] = regs->addr_cmap; 83552891Sbostic 83652891Sbostic /* set color map entry zero to zero */ 83752891Sbostic bt459_select_reg(regs, 0); 83852891Sbostic regs->addr_cmap = 0; 83952891Sbostic MachEmptyWriteBuffer(); 84052891Sbostic regs->addr_cmap = 0; 84152891Sbostic MachEmptyWriteBuffer(); 84252891Sbostic regs->addr_cmap = 0; 84352891Sbostic MachEmptyWriteBuffer(); 84452891Sbostic 84552891Sbostic /* disable display */ 84652891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0); 84752891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0); 84852891Sbostic 84952891Sbostic vstate.off = 1; 85052891Sbostic } 85156819Sralph 85256819Sralph /* 85356819Sralph * cfb keyboard and mouse input. Just punt to the generic ones in fb.c 85456819Sralph */ 85556819Sralph void 85656819Sralph cfbKbdEvent(ch) 85756819Sralph int ch; 85856819Sralph { 85956819Sralph fbKbdEvent(ch, &cfbfb); 86056819Sralph } 86156819Sralph 86256819Sralph void 86356819Sralph cfbMouseEvent(newRepPtr) 86456819Sralph MouseReport *newRepPtr; 86556819Sralph { 86656819Sralph fbMouseEvent(newRepPtr, &cfbfb); 86756819Sralph } 86856819Sralph 86956819Sralph void 87056819Sralph cfbMouseButtons(newRepPtr) 87156819Sralph MouseReport *newRepPtr; 87256819Sralph { 87356819Sralph fbMouseButtons(newRepPtr, &cfbfb); 87456819Sralph } 87556819Sralph 87656819Sralph /* 87756819Sralph * Configure the mouse and keyboard based on machine type 87856819Sralph */ 87956819Sralph static void 88056819Sralph cfbConfigMouse() 88156819Sralph { 88256819Sralph int s; 88356819Sralph 88456819Sralph s = spltty(); 88556819Sralph switch (pmax_boardtype) { 88656819Sralph #if NDC > 0 88756819Sralph case DS_3MAX: 88856819Sralph dcDivertXInput = cfbKbdEvent; 88956819Sralph dcMouseEvent = cfbMouseEvent; 89056819Sralph dcMouseButtons = cfbMouseButtons; 89156819Sralph break; 89252891Sbostic #endif 89356819Sralph #if NSCC > 1 89456819Sralph case DS_3MIN: 89556819Sralph sccDivertXInput = cfbKbdEvent; 89656819Sralph sccMouseEvent = cfbMouseEvent; 89756819Sralph sccMouseButtons = cfbMouseButtons; 89856819Sralph break; 89956819Sralph #endif 90056819Sralph #if NDTOP > 0 90156819Sralph case DS_MAXINE: 90256819Sralph dtopDivertXInput = cfbKbdEvent; 90356819Sralph dtopMouseEvent = cfbMouseEvent; 90456819Sralph dtopMouseButtons = cfbMouseButtons; 90556819Sralph break; 90656819Sralph #endif 90756819Sralph default: 90856819Sralph printf("Can't configure mouse/keyboard\n"); 90956819Sralph }; 91056819Sralph splx(s); 91156819Sralph } 91256819Sralph 91356819Sralph /* 91456819Sralph * and deconfigure them 91556819Sralph */ 91656819Sralph static void 91756819Sralph cfbDeconfigMouse() 91856819Sralph { 91956819Sralph int s; 92056819Sralph 92156819Sralph s = spltty(); 92256819Sralph switch (pmax_boardtype) { 92356819Sralph #if NDC > 0 92456819Sralph case DS_3MAX: 92556819Sralph dcDivertXInput = (void (*)())0; 92656819Sralph dcMouseEvent = (void (*)())0; 92756819Sralph dcMouseButtons = (void (*)())0; 92856819Sralph break; 92956819Sralph #endif 93056819Sralph #if NSCC > 1 93156819Sralph case DS_3MIN: 93256819Sralph sccDivertXInput = (void (*)())0; 93356819Sralph sccMouseEvent = (void (*)())0; 93456819Sralph sccMouseButtons = (void (*)())0; 93556819Sralph break; 93656819Sralph #endif 93756819Sralph #if NDTOP > 0 93856819Sralph case DS_MAXINE: 93956819Sralph dtopDivertXInput = (void (*)())0; 94056819Sralph dtopMouseEvent = (void (*)())0; 94156819Sralph dtopMouseButtons = (void (*)())0; 94256819Sralph break; 94356819Sralph #endif 94456819Sralph default: 94556819Sralph printf("Can't deconfigure mouse/keyboard\n"); 94656819Sralph }; 94756819Sralph } 94856819Sralph #endif /* NCFB */ 949