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 652891Sbostic * Ralph Campbell. 752891Sbostic * 852891Sbostic * %sccs.include.redist.c% 952891Sbostic * 10*56525Sbostic * @(#)cfb.c 7.4 (Berkeley) 10/11/92 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 5552891Sbostic #include "cfb.h" 5652891Sbostic #if NCFB > 0 5752891Sbostic 5852891Sbostic /* 5952891Sbostic * This is a device driver for the PMAG-BA color frame buffer 6052891Sbostic * on the TURBOchannel. 6152891Sbostic * XXX This is just to get a console working; 6252891Sbostic * it will need changes to work with X11R5. 6352891Sbostic */ 6452891Sbostic 6556522Sbostic #include <sys/param.h> 6656522Sbostic #include <sys/time.h> 6756522Sbostic #include <sys/kernel.h> 6856522Sbostic #include <sys/ioctl.h> 6956522Sbostic #include <sys/file.h> 7056522Sbostic #include <sys/errno.h> 7156522Sbostic #include <sys/proc.h> 7256522Sbostic #include <sys/mman.h> 7352891Sbostic 7456522Sbostic #include <vm/vm.h> 7552891Sbostic 7656522Sbostic #include <machine/machConst.h> 7756522Sbostic #include <machine/machMon.h> 7856522Sbostic #include <machine/dc7085cons.h> 7956522Sbostic #include <machine/pmioctl.h> 8052891Sbostic 81*56525Sbostic #include <pmax/dev/device.h> 82*56525Sbostic #include <pmax/dev/cfbreg.h> 83*56525Sbostic #include <pmax/dev/font.c> 8456522Sbostic 8552891Sbostic #define MAX_ROW 56 8652891Sbostic #define MAX_COL 80 8752891Sbostic 8852891Sbostic /* 8952891Sbostic * Macro to translate from a time struct to milliseconds. 9052891Sbostic */ 9152891Sbostic #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) 9252891Sbostic 9352891Sbostic static int isMono; /* true if B&W frame buffer */ 9452891Sbostic static int initialized; /* true if 'probe' was successful */ 9552891Sbostic static int GraphicsOpen; /* true if the graphics device is open */ 9652891Sbostic static int row, col; /* row and col for console cursor */ 9752891Sbostic static struct selinfo cfb_selp; /* process waiting for select */ 9852891Sbostic static unsigned fb_addr; /* frame buffer kernel virtual address */ 9952891Sbostic static unsigned planemask_addr; /* plane mask kernel virtual address */ 10052891Sbostic 10152891Sbostic /* 10252891Sbostic * These need to be mapped into user space. 10352891Sbostic */ 10452891Sbostic static struct pmuaccess { 10552891Sbostic PM_Info scrInfo; 10652891Sbostic pmEvent events[PM_MAXEVQ]; 10752891Sbostic pmTimeCoord tcs[MOTION_BUFFER_SIZE]; 10852891Sbostic } pmu; 10952891Sbostic 11052891Sbostic /* 11152891Sbostic * Font mask bits used by Blitc(). 11252891Sbostic */ 11352891Sbostic static unsigned int fontmaskBits[16] = { 11452891Sbostic 0x00000000, 11552891Sbostic 0x00000001, 11652891Sbostic 0x00000100, 11752891Sbostic 0x00000101, 11852891Sbostic 0x00010000, 11952891Sbostic 0x00010001, 12052891Sbostic 0x00010100, 12152891Sbostic 0x00010101, 12252891Sbostic 0x01000000, 12352891Sbostic 0x01000001, 12452891Sbostic 0x01000100, 12552891Sbostic 0x01000101, 12652891Sbostic 0x01010000, 12752891Sbostic 0x01010001, 12852891Sbostic 0x01010100, 12952891Sbostic 0x01010101 13052891Sbostic }; 13152891Sbostic 13252891Sbostic /* 13352891Sbostic * Forward references. 13452891Sbostic */ 13552891Sbostic static void Scroll(); 13652891Sbostic static void Blitc(); 13752891Sbostic 13852891Sbostic static void ScreenInit(); 13952891Sbostic static void LoadCursor(); 14052891Sbostic static void RestoreCursorColor(); 14152891Sbostic static void CursorColor(); 14252891Sbostic static void PosCursor(); 14352891Sbostic static void InitColorMap(); 14452891Sbostic static void LoadColorMap(); 14552891Sbostic static void EnableVideo(); 14652891Sbostic static void DisableVideo(); 14752891Sbostic 14852891Sbostic extern void dcKBDPutc(); 14952891Sbostic extern void (*dcDivertXInput)(); 15052891Sbostic extern void (*dcMouseEvent)(); 15152891Sbostic extern void (*dcMouseButtons)(); 15252891Sbostic 15352891Sbostic int cfbprobe(); 15452891Sbostic struct driver cfbdriver = { 15552891Sbostic "cfb", cfbprobe, 0, 0, 15652891Sbostic }; 15752891Sbostic 15852891Sbostic /* 15952891Sbostic * Test to see if device is present. 16052891Sbostic * Return true if found and initialized ok. 16152891Sbostic */ 16252891Sbostic cfbprobe(cp) 16352891Sbostic register struct pmax_ctlr *cp; 16452891Sbostic { 16552891Sbostic 16652891Sbostic if (!initialized) { 16752891Sbostic if (!cfb_init(cp)) 16852891Sbostic return (0); 16952891Sbostic } 17052891Sbostic printf("cfb%d at nexus0 csr 0x%x priority %d\n", 17152891Sbostic cp->pmax_unit, cp->pmax_addr, cp->pmax_pri); 17252891Sbostic return (1); 17352891Sbostic } 17452891Sbostic 17552891Sbostic /* 17652891Sbostic *---------------------------------------------------------------------- 17752891Sbostic * 17852891Sbostic * cfbKbdEvent -- 17952891Sbostic * 18052891Sbostic * Process a received character. 18152891Sbostic * 18252891Sbostic * Results: 18352891Sbostic * None. 18452891Sbostic * 18552891Sbostic * Side effects: 18652891Sbostic * Events added to the queue. 18752891Sbostic * 18852891Sbostic *---------------------------------------------------------------------- 18952891Sbostic */ 19052891Sbostic void 19152891Sbostic cfbKbdEvent(ch) 19252891Sbostic int ch; 19352891Sbostic { 19452891Sbostic register pmEvent *eventPtr; 19552891Sbostic int i; 19652891Sbostic 19752891Sbostic if (!GraphicsOpen) 19852891Sbostic return; 19952891Sbostic 20052891Sbostic /* 20152891Sbostic * See if there is room in the queue. 20252891Sbostic */ 20352891Sbostic i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 20452891Sbostic if (i == pmu.scrInfo.qe.eHead) 20552891Sbostic return; 20652891Sbostic 20752891Sbostic /* 20852891Sbostic * Add the event to the queue. 20952891Sbostic */ 21052891Sbostic eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 21152891Sbostic eventPtr->type = BUTTON_RAW_TYPE; 21252891Sbostic eventPtr->device = KEYBOARD_DEVICE; 21352891Sbostic eventPtr->x = pmu.scrInfo.mouse.x; 21452891Sbostic eventPtr->y = pmu.scrInfo.mouse.y; 21552891Sbostic eventPtr->time = TO_MS(time); 21652891Sbostic eventPtr->key = ch; 21752891Sbostic pmu.scrInfo.qe.eTail = i; 21852891Sbostic selwakeup(&cfb_selp); 21952891Sbostic } 22052891Sbostic 22152891Sbostic /* 22252891Sbostic *---------------------------------------------------------------------- 22352891Sbostic * 22452891Sbostic * cfbMouseEvent -- 22552891Sbostic * 22652891Sbostic * Process a mouse event. 22752891Sbostic * 22852891Sbostic * Results: 22952891Sbostic * None. 23052891Sbostic * 23152891Sbostic * Side effects: 23252891Sbostic * An event is added to the event queue. 23352891Sbostic * 23452891Sbostic *---------------------------------------------------------------------- 23552891Sbostic */ 23652891Sbostic void 23752891Sbostic cfbMouseEvent(newRepPtr) 23852891Sbostic register MouseReport *newRepPtr; 23952891Sbostic { 24052891Sbostic unsigned milliSec; 24152891Sbostic int i; 24252891Sbostic pmEvent *eventPtr; 24352891Sbostic 24452891Sbostic if (!GraphicsOpen) 24552891Sbostic return; 24652891Sbostic 24752891Sbostic milliSec = TO_MS(time); 24852891Sbostic 24952891Sbostic /* 25052891Sbostic * Check to see if we have to accelerate the mouse 25152891Sbostic */ 25252891Sbostic if (pmu.scrInfo.mscale >= 0) { 25352891Sbostic if (newRepPtr->dx >= pmu.scrInfo.mthreshold) { 25452891Sbostic newRepPtr->dx += 25552891Sbostic (newRepPtr->dx - pmu.scrInfo.mthreshold) * 25652891Sbostic pmu.scrInfo.mscale; 25752891Sbostic } 25852891Sbostic if (newRepPtr->dy >= pmu.scrInfo.mthreshold) { 25952891Sbostic newRepPtr->dy += 26052891Sbostic (newRepPtr->dy - pmu.scrInfo.mthreshold) * 26152891Sbostic pmu.scrInfo.mscale; 26252891Sbostic } 26352891Sbostic } 26452891Sbostic 26552891Sbostic /* 26652891Sbostic * Update mouse position 26752891Sbostic */ 26852891Sbostic if (newRepPtr->state & MOUSE_X_SIGN) { 26952891Sbostic pmu.scrInfo.mouse.x += newRepPtr->dx; 27052891Sbostic if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x) 27152891Sbostic pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x; 27252891Sbostic } else { 27352891Sbostic pmu.scrInfo.mouse.x -= newRepPtr->dx; 27452891Sbostic if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x) 27552891Sbostic pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x; 27652891Sbostic } 27752891Sbostic if (newRepPtr->state & MOUSE_Y_SIGN) { 27852891Sbostic pmu.scrInfo.mouse.y -= newRepPtr->dy; 27952891Sbostic if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y) 28052891Sbostic pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y; 28152891Sbostic } else { 28252891Sbostic pmu.scrInfo.mouse.y += newRepPtr->dy; 28352891Sbostic if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y) 28452891Sbostic pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y; 28552891Sbostic } 28652891Sbostic 28752891Sbostic /* 28852891Sbostic * Move the hardware cursor. 28952891Sbostic */ 29052891Sbostic PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 29152891Sbostic 29252891Sbostic /* 29352891Sbostic * Store the motion event in the motion buffer. 29452891Sbostic */ 29552891Sbostic pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec; 29652891Sbostic pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x; 29752891Sbostic pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y; 29852891Sbostic if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE) 29952891Sbostic pmu.scrInfo.qe.tcNext = 0; 30052891Sbostic if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom && 30152891Sbostic pmu.scrInfo.mouse.y >= pmu.scrInfo.mbox.top && 30252891Sbostic pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right && 30352891Sbostic pmu.scrInfo.mouse.x >= pmu.scrInfo.mbox.left) 30452891Sbostic return; 30552891Sbostic 30652891Sbostic pmu.scrInfo.mbox.bottom = 0; 30752891Sbostic if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead) 30852891Sbostic return; 30952891Sbostic 31052891Sbostic i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1); 31152891Sbostic if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && 31252891Sbostic (i != pmu.scrInfo.qe.eHead)) { 31352891Sbostic pmEvent *eventPtr; 31452891Sbostic 31552891Sbostic eventPtr = &pmu.events[i]; 31652891Sbostic if (eventPtr->type == MOTION_TYPE) { 31752891Sbostic eventPtr->x = pmu.scrInfo.mouse.x; 31852891Sbostic eventPtr->y = pmu.scrInfo.mouse.y; 31952891Sbostic eventPtr->time = milliSec; 32052891Sbostic eventPtr->device = MOUSE_DEVICE; 32152891Sbostic return; 32252891Sbostic } 32352891Sbostic } 32452891Sbostic /* 32552891Sbostic * Put event into queue and wakeup any waiters. 32652891Sbostic */ 32752891Sbostic eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 32852891Sbostic eventPtr->type = MOTION_TYPE; 32952891Sbostic eventPtr->time = milliSec; 33052891Sbostic eventPtr->x = pmu.scrInfo.mouse.x; 33152891Sbostic eventPtr->y = pmu.scrInfo.mouse.y; 33252891Sbostic eventPtr->device = MOUSE_DEVICE; 33352891Sbostic pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 33452891Sbostic selwakeup(&cfb_selp); 33552891Sbostic } 33652891Sbostic 33752891Sbostic /* 33852891Sbostic *---------------------------------------------------------------------- 33952891Sbostic * 34052891Sbostic * cfbMouseButtons -- 34152891Sbostic * 34252891Sbostic * Process mouse buttons. 34352891Sbostic * 34452891Sbostic * Results: 34552891Sbostic * None. 34652891Sbostic * 34752891Sbostic * Side effects: 34852891Sbostic * None. 34952891Sbostic * 35052891Sbostic *---------------------------------------------------------------------- 35152891Sbostic */ 35252891Sbostic void 35352891Sbostic cfbMouseButtons(newRepPtr) 35452891Sbostic MouseReport *newRepPtr; 35552891Sbostic { 35652891Sbostic static char temp, oldSwitch, newSwitch; 35752891Sbostic int i, j; 35852891Sbostic pmEvent *eventPtr; 35952891Sbostic static MouseReport lastRep; 36052891Sbostic 36152891Sbostic if (!GraphicsOpen) 36252891Sbostic return; 36352891Sbostic 36452891Sbostic newSwitch = newRepPtr->state & 0x07; 36552891Sbostic oldSwitch = lastRep.state & 0x07; 36652891Sbostic 36752891Sbostic temp = oldSwitch ^ newSwitch; 36852891Sbostic if (temp == 0) 36952891Sbostic return; 37052891Sbostic for (j = 1; j < 8; j <<= 1) { 37152891Sbostic if ((j & temp) == 0) 37252891Sbostic continue; 37352891Sbostic 37452891Sbostic /* 37552891Sbostic * Check for room in the queue 37652891Sbostic */ 37752891Sbostic i = PM_EVROUND(pmu.scrInfo.qe.eTail+1); 37852891Sbostic if (i == pmu.scrInfo.qe.eHead) 37952891Sbostic return; 38052891Sbostic 38152891Sbostic /* 38252891Sbostic * Put event into queue. 38352891Sbostic */ 38452891Sbostic eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 38552891Sbostic 38652891Sbostic switch (j) { 38752891Sbostic case RIGHT_BUTTON: 38852891Sbostic eventPtr->key = EVENT_RIGHT_BUTTON; 38952891Sbostic break; 39052891Sbostic 39152891Sbostic case MIDDLE_BUTTON: 39252891Sbostic eventPtr->key = EVENT_MIDDLE_BUTTON; 39352891Sbostic break; 39452891Sbostic 39552891Sbostic case LEFT_BUTTON: 39652891Sbostic eventPtr->key = EVENT_LEFT_BUTTON; 39752891Sbostic } 39852891Sbostic if (newSwitch & j) 39952891Sbostic eventPtr->type = BUTTON_DOWN_TYPE; 40052891Sbostic else 40152891Sbostic eventPtr->type = BUTTON_UP_TYPE; 40252891Sbostic eventPtr->device = MOUSE_DEVICE; 40352891Sbostic 40452891Sbostic eventPtr->time = TO_MS(time); 40552891Sbostic eventPtr->x = pmu.scrInfo.mouse.x; 40652891Sbostic eventPtr->y = pmu.scrInfo.mouse.y; 40752891Sbostic } 40852891Sbostic pmu.scrInfo.qe.eTail = i; 40952891Sbostic selwakeup(&cfb_selp); 41052891Sbostic 41152891Sbostic lastRep = *newRepPtr; 41252891Sbostic pmu.scrInfo.mswitches = newSwitch; 41352891Sbostic } 41452891Sbostic 41552891Sbostic /* 41652891Sbostic *---------------------------------------------------------------------- 41752891Sbostic * 41852891Sbostic * Scroll -- 41952891Sbostic * 42052891Sbostic * Scroll the screen. 42152891Sbostic * 42252891Sbostic * Results: 42352891Sbostic * None. 42452891Sbostic * 42552891Sbostic * Side effects: 42652891Sbostic * None. 42752891Sbostic * 42852891Sbostic *---------------------------------------------------------------------- 42952891Sbostic */ 43052891Sbostic static void 43152891Sbostic Scroll() 43252891Sbostic { 43352891Sbostic register int *dest, *src; 43452891Sbostic register int *end; 43552891Sbostic register int temp0, temp1, temp2, temp3; 43652891Sbostic register int i, scanInc, lineCount; 43752891Sbostic int line; 43852891Sbostic 43952891Sbostic /* 44052891Sbostic * If the mouse is on we don't scroll so that the bit map remains sane. 44152891Sbostic */ 44252891Sbostic if (GraphicsOpen) { 44352891Sbostic row = 0; 44452891Sbostic return; 44552891Sbostic } 44652891Sbostic 44752891Sbostic /* 44852891Sbostic * The following is an optimization to cause the scrolling 44952891Sbostic * of text to be memory limited. Basically the writebuffer is 45052891Sbostic * 4 words (32 bits ea.) long so to achieve maximum speed we 45152891Sbostic * read and write in multiples of 4 words. We also limit the 45252891Sbostic * size to be MAX_COL characters for more speed. 45352891Sbostic */ 45452891Sbostic if (isMono) { 45552891Sbostic lineCount = 5; 45652891Sbostic line = 1920 * 2; 45752891Sbostic scanInc = 44; 45852891Sbostic } else { 45952891Sbostic lineCount = 40; 46052891Sbostic scanInc = 96; 46152891Sbostic line = 1920 * 8; 46252891Sbostic } 46352891Sbostic src = (int *)(fb_addr + line); 46452891Sbostic dest = (int *)(fb_addr); 46552891Sbostic end = (int *)(fb_addr + (60 * line) - line); 46652891Sbostic do { 46752891Sbostic i = 0; 46852891Sbostic do { 46952891Sbostic temp0 = src[0]; 47052891Sbostic temp1 = src[1]; 47152891Sbostic temp2 = src[2]; 47252891Sbostic temp3 = src[3]; 47352891Sbostic dest[0] = temp0; 47452891Sbostic dest[1] = temp1; 47552891Sbostic dest[2] = temp2; 47652891Sbostic dest[3] = temp3; 47752891Sbostic dest += 4; 47852891Sbostic src += 4; 47952891Sbostic i++; 48052891Sbostic } while (i < lineCount); 48152891Sbostic src += scanInc; 48252891Sbostic dest += scanInc; 48352891Sbostic } while (src < end); 48452891Sbostic 48552891Sbostic /* 48652891Sbostic * Now zero out the last two lines 48752891Sbostic */ 48852891Sbostic bzero(fb_addr + (row * line), 3 * line); 48952891Sbostic } 49052891Sbostic 49152891Sbostic /* 49252891Sbostic *---------------------------------------------------------------------- 49352891Sbostic * 49452891Sbostic * cfbPutc -- 49552891Sbostic * 49652891Sbostic * Write a character to the console. 49752891Sbostic * 49852891Sbostic * Results: 49952891Sbostic * None. 50052891Sbostic * 50152891Sbostic * Side effects: 50252891Sbostic * None. 50352891Sbostic * 50452891Sbostic *---------------------------------------------------------------------- 50552891Sbostic */ 50652891Sbostic cfbPutc(c) 50752891Sbostic register int c; 50852891Sbostic { 50952891Sbostic int s; 51052891Sbostic 51152891Sbostic s = splhigh(); /* in case we do any printf's at interrupt time */ 51252891Sbostic if (initialized) { 51352891Sbostic #ifdef DEBUG 51452891Sbostic /* 51552891Sbostic * If the HELP key is pressed, wait for another 51652891Sbostic * HELP key press to start/stop output. 51752891Sbostic */ 51852891Sbostic if (dcDebugGetc() == LK_HELP) { 51952891Sbostic while (dcDebugGetc() != LK_HELP) 52052891Sbostic ; 52152891Sbostic } 52252891Sbostic #endif 52352891Sbostic Blitc(c); 52452891Sbostic } else { 52552891Sbostic void (*f)() = (void (*)())MACH_MON_PUTCHAR; 52652891Sbostic 52752891Sbostic (*f)(c); 52852891Sbostic } 52952891Sbostic splx(s); 53052891Sbostic } 53152891Sbostic 53252891Sbostic /* 53352891Sbostic *---------------------------------------------------------------------- 53452891Sbostic * 53552891Sbostic * Blitc -- 53652891Sbostic * 53752891Sbostic * Write a character to the screen. 53852891Sbostic * 53952891Sbostic * Results: 54052891Sbostic * None. 54152891Sbostic * 54252891Sbostic * Side effects: 54352891Sbostic * None. 54452891Sbostic * 54552891Sbostic *---------------------------------------------------------------------- 54652891Sbostic */ 54752891Sbostic static void 54852891Sbostic Blitc(c) 54952891Sbostic register int c; 55052891Sbostic { 55152891Sbostic register char *bRow, *fRow; 55252891Sbostic register int i; 55352891Sbostic register int ote = isMono ? 256 : 1024; /* offset to table entry */ 55452891Sbostic int colMult = isMono ? 1 : 8; 55552891Sbostic 55652891Sbostic c &= 0xff; 55752891Sbostic 55852891Sbostic switch (c) { 55952891Sbostic case '\t': 56052891Sbostic for (i = 8 - (col & 0x7); i > 0; i--) 56152891Sbostic Blitc(' '); 56252891Sbostic break; 56352891Sbostic 56452891Sbostic case '\r': 56552891Sbostic col = 0; 56652891Sbostic break; 56752891Sbostic 56852891Sbostic case '\b': 56952891Sbostic col--; 57052891Sbostic if (col < 0) 57152891Sbostic col = 0; 57252891Sbostic break; 57352891Sbostic 57452891Sbostic case '\n': 57552891Sbostic if (row + 1 >= MAX_ROW) 57652891Sbostic Scroll(); 57752891Sbostic else 57852891Sbostic row++; 57952891Sbostic col = 0; 58052891Sbostic break; 58152891Sbostic 58252891Sbostic case '\007': 58352891Sbostic dcKBDPutc(LK_RING_BELL); 58452891Sbostic break; 58552891Sbostic 58652891Sbostic default: 58752891Sbostic /* 58852891Sbostic * 0xA1 to 0xFD are the printable characters added with 8-bit 58952891Sbostic * support. 59052891Sbostic */ 59152891Sbostic if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD) 59252891Sbostic break; 59352891Sbostic /* 59452891Sbostic * If the next character will wrap around then 59552891Sbostic * increment row counter or scroll screen. 59652891Sbostic */ 59752891Sbostic if (col >= MAX_COL) { 59852891Sbostic col = 0; 59952891Sbostic if (row + 1 >= MAX_ROW) 60052891Sbostic Scroll(); 60152891Sbostic else 60252891Sbostic row++; 60352891Sbostic } 60452891Sbostic bRow = (char *)(fb_addr + 60552891Sbostic (row * 15 & 0x3ff) * ote + col * colMult); 60652891Sbostic i = c - ' '; 60752891Sbostic /* 60852891Sbostic * This is to skip the (32) 8-bit 60952891Sbostic * control chars, as well as DEL 61052891Sbostic * and 0xA0 which aren't printable 61152891Sbostic */ 61252891Sbostic if (c > '~') 61352891Sbostic i -= 34; 61452891Sbostic i *= 15; 61552891Sbostic fRow = (char *)((int)pmFont + i); 61652891Sbostic 61752891Sbostic /* inline expansion for speed */ 61852891Sbostic if (isMono) { 61952891Sbostic *bRow = *fRow++; bRow += ote; 62052891Sbostic *bRow = *fRow++; bRow += ote; 62152891Sbostic *bRow = *fRow++; bRow += ote; 62252891Sbostic *bRow = *fRow++; bRow += ote; 62352891Sbostic *bRow = *fRow++; bRow += ote; 62452891Sbostic *bRow = *fRow++; bRow += ote; 62552891Sbostic *bRow = *fRow++; bRow += ote; 62652891Sbostic *bRow = *fRow++; bRow += ote; 62752891Sbostic *bRow = *fRow++; bRow += ote; 62852891Sbostic *bRow = *fRow++; bRow += ote; 62952891Sbostic *bRow = *fRow++; bRow += ote; 63052891Sbostic *bRow = *fRow++; bRow += ote; 63152891Sbostic *bRow = *fRow++; bRow += ote; 63252891Sbostic *bRow = *fRow++; bRow += ote; 63352891Sbostic *bRow = *fRow++; bRow += ote; 63452891Sbostic } else { 63552891Sbostic register int j; 63652891Sbostic register unsigned int *pInt; 63752891Sbostic 63852891Sbostic pInt = (unsigned int *)bRow; 63952891Sbostic for (j = 0; j < 15; j++) { 64052891Sbostic /* 64152891Sbostic * fontmaskBits converts a nibble 64252891Sbostic * (4 bytes) to a long word 64352891Sbostic * containing 4 pixels corresponding 64452891Sbostic * to each bit in the nibble. Thus 64552891Sbostic * we write two longwords for each 64652891Sbostic * byte in font. 64752891Sbostic * 64852891Sbostic * Remember the font is 8 bits wide 64952891Sbostic * and 15 bits high. 65052891Sbostic * 65152891Sbostic * We add 256 to the pointer to 65252891Sbostic * point to the pixel on the 65352891Sbostic * next scan line 65452891Sbostic * directly below the current 65552891Sbostic * pixel. 65652891Sbostic */ 65752891Sbostic pInt[0] = fontmaskBits[(*fRow) & 0xf]; 65852891Sbostic pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf]; 65952891Sbostic fRow++; 66052891Sbostic pInt += 256; 66152891Sbostic } 66252891Sbostic } 66352891Sbostic col++; /* increment column counter */ 66452891Sbostic } 66552891Sbostic if (!GraphicsOpen) 66652891Sbostic PosCursor(col * 8, row * 15); 66752891Sbostic } 66852891Sbostic 66952891Sbostic /*ARGSUSED*/ 67052891Sbostic cfbopen(dev, flag) 67152891Sbostic dev_t dev; 67252891Sbostic int flag; 67352891Sbostic { 67452891Sbostic 67552891Sbostic if (!initialized) 67652891Sbostic return (ENXIO); 67752891Sbostic if (GraphicsOpen) 67852891Sbostic return (EBUSY); 67952891Sbostic 68052891Sbostic GraphicsOpen = 1; 68152891Sbostic if (!isMono) 68252891Sbostic InitColorMap(); 68352891Sbostic /* 68452891Sbostic * Set up event queue for later 68552891Sbostic */ 68652891Sbostic pmu.scrInfo.qe.eSize = PM_MAXEVQ; 68752891Sbostic pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 68852891Sbostic pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 68952891Sbostic pmu.scrInfo.qe.tcNext = 0; 69052891Sbostic pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 69152891Sbostic return (0); 69252891Sbostic } 69352891Sbostic 69452891Sbostic /*ARGSUSED*/ 69552891Sbostic cfbclose(dev, flag) 69652891Sbostic dev_t dev; 69752891Sbostic int flag; 69852891Sbostic { 69952959Sralph int s; 70052891Sbostic 70152891Sbostic if (!GraphicsOpen) 70252891Sbostic return (EBADF); 70352891Sbostic 70452891Sbostic GraphicsOpen = 0; 70552891Sbostic if (!isMono) 70652891Sbostic InitColorMap(); 70752959Sralph s = spltty(); 70852959Sralph dcDivertXInput = (void (*)())0; 70952959Sralph dcMouseEvent = (void (*)())0; 71052959Sralph dcMouseButtons = (void (*)())0; 71152959Sralph splx(s); 71252891Sbostic ScreenInit(); 71352891Sbostic vmUserUnmap(); 71452891Sbostic bzero(fb_addr, (isMono ? 1024 / 8 : 1024) * 864); 71552891Sbostic PosCursor(col * 8, row * 15); 71652891Sbostic return (0); 71752891Sbostic } 71852891Sbostic 71952891Sbostic /*ARGSUSED*/ 72052891Sbostic cfbioctl(dev, cmd, data, flag) 72152891Sbostic dev_t dev; 72252891Sbostic caddr_t data; 72352891Sbostic { 72452959Sralph int s; 72552891Sbostic 72652891Sbostic switch (cmd) { 72752891Sbostic case QIOCGINFO: 72852891Sbostic { 72952891Sbostic caddr_t addr; 73052891Sbostic extern caddr_t vmUserMap(); 73152891Sbostic 73252891Sbostic /* 73352891Sbostic * Map the all the data the user needs access to into 73452891Sbostic * user space. 73552891Sbostic */ 73652891Sbostic addr = vmUserMap(sizeof(pmu), (unsigned)&pmu); 73752891Sbostic if (addr == (caddr_t)0) 73852891Sbostic goto mapError; 73952891Sbostic *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo; 74052891Sbostic pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events; 74152891Sbostic pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs; 74252891Sbostic /* 74352891Sbostic * Map the plane mask into the user's address space. 74452891Sbostic */ 74552891Sbostic addr = vmUserMap(4, planemask_addr); 74652891Sbostic if (addr == (caddr_t)0) 74752891Sbostic goto mapError; 74852891Sbostic pmu.scrInfo.planemask = (char *)addr; 74952891Sbostic /* 75052891Sbostic * Map the frame buffer into the user's address space. 75152891Sbostic */ 75252891Sbostic addr = vmUserMap(isMono ? 256*1024 : 1024*1024, fb_addr); 75352891Sbostic if (addr == (caddr_t)0) 75452891Sbostic goto mapError; 75552891Sbostic pmu.scrInfo.bitmap = (char *)addr; 75652891Sbostic break; 75752891Sbostic 75852891Sbostic mapError: 75952891Sbostic vmUserUnmap(); 76052891Sbostic printf("Cannot map shared data structures\n"); 76152891Sbostic return (EIO); 76252891Sbostic } 76352891Sbostic 76452891Sbostic case QIOCPMSTATE: 76552891Sbostic /* 76652891Sbostic * Set mouse state. 76752891Sbostic */ 76852891Sbostic pmu.scrInfo.mouse = *(pmCursor *)data; 76952891Sbostic PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 77052891Sbostic break; 77152891Sbostic 77252891Sbostic case QIOCINIT: 77352891Sbostic /* 77452891Sbostic * Initialize the screen. 77552891Sbostic */ 77652891Sbostic ScreenInit(); 77752891Sbostic break; 77852891Sbostic 77952891Sbostic case QIOCKPCMD: 78052891Sbostic { 78152891Sbostic pmKpCmd *kpCmdPtr; 78252891Sbostic unsigned char *cp; 78352891Sbostic 78452891Sbostic kpCmdPtr = (pmKpCmd *)data; 78552891Sbostic if (kpCmdPtr->nbytes == 0) 78652891Sbostic kpCmdPtr->cmd |= 0x80; 78752891Sbostic if (!GraphicsOpen) 78852891Sbostic kpCmdPtr->cmd |= 1; 78952891Sbostic dcKBDPutc((int)kpCmdPtr->cmd); 79052891Sbostic cp = &kpCmdPtr->par[0]; 79152891Sbostic for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 79252891Sbostic if (kpCmdPtr->nbytes == 1) 79352891Sbostic *cp |= 0x80; 79452891Sbostic dcKBDPutc((int)*cp); 79552891Sbostic } 79652891Sbostic break; 79752891Sbostic } 79852891Sbostic 79952891Sbostic case QIOCADDR: 80052891Sbostic *(PM_Info **)data = &pmu.scrInfo; 80152891Sbostic break; 80252891Sbostic 80352891Sbostic case QIOWCURSOR: 80452891Sbostic LoadCursor((unsigned short *)data); 80552891Sbostic break; 80652891Sbostic 80752891Sbostic case QIOWCURSORCOLOR: 80852891Sbostic CursorColor((unsigned int *)data); 80952891Sbostic break; 81052891Sbostic 81152891Sbostic case QIOSETCMAP: 81252891Sbostic LoadColorMap((ColorMap *)data); 81352891Sbostic break; 81452891Sbostic 81552891Sbostic case QIOKERNLOOP: 81652959Sralph s = spltty(); 81752891Sbostic dcDivertXInput = cfbKbdEvent; 81852891Sbostic dcMouseEvent = cfbMouseEvent; 81952891Sbostic dcMouseButtons = cfbMouseButtons; 82052959Sralph splx(s); 82152891Sbostic break; 82252891Sbostic 82352891Sbostic case QIOKERNUNLOOP: 82452959Sralph s = spltty(); 82552891Sbostic dcDivertXInput = (void (*)())0; 82652891Sbostic dcMouseEvent = (void (*)())0; 82752891Sbostic dcMouseButtons = (void (*)())0; 82852959Sralph splx(s); 82952891Sbostic break; 83052891Sbostic 83152891Sbostic case QIOVIDEOON: 83252891Sbostic EnableVideo(); 83352891Sbostic break; 83452891Sbostic 83552891Sbostic case QIOVIDEOOFF: 83652891Sbostic DisableVideo(); 83752891Sbostic break; 83852891Sbostic 83952891Sbostic default: 84052891Sbostic printf("cfb0: Unknown ioctl command %x\n", cmd); 84152891Sbostic return (EINVAL); 84252891Sbostic } 84352891Sbostic return (0); 84452891Sbostic } 84552891Sbostic 84652891Sbostic cfbselect(dev, flag, p) 84752891Sbostic dev_t dev; 84852891Sbostic int flag; 84952891Sbostic struct proc *p; 85052891Sbostic { 85152891Sbostic 85252891Sbostic switch (flag) { 85352891Sbostic case FREAD: 85452891Sbostic if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail) 85552891Sbostic return (1); 85652891Sbostic selrecord(p, &cfb_selp); 85752891Sbostic break; 85852891Sbostic } 85952891Sbostic 86052891Sbostic return (0); 86152891Sbostic } 86252891Sbostic 86352891Sbostic static u_char cursor_RGB[6]; /* cursor color 2 & 3 */ 86452891Sbostic 86552891Sbostic /* 86652891Sbostic * The default cursor. 86752891Sbostic */ 86852891Sbostic static unsigned short defCursor[1024] = { 86952891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87052891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87152891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87252891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87352891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87452891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87552891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87652891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87752891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87852891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 87952891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88052891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88152891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88252891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88352891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88452891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88552891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88652891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88752891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88852891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 88952891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89052891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89152891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89252891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89352891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89452891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89552891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89652891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89752891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89852891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 89952891Sbostic 0x00FF, 0x00FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 90052891Sbostic 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 90152891Sbostic }; 90252891Sbostic 90352891Sbostic #define CFB_OFFSET_VRAM 0x0 /* from module's base */ 90452891Sbostic /* Replicated at x100000 */ 90552891Sbostic #define CFB_OFFSET_BT459 0x200000 /* Bt459 registers */ 90652891Sbostic #define CFB_OFFSET_IREQ 0x300000 /* Interrupt req. control */ 90752891Sbostic #define CFB_OFFSET_ROM 0x380000 /* Diagnostic ROM */ 90852891Sbostic #define CFB_OFFSET_RESET 0x3c0000 /* Bt459 resets on writes */ 90952891Sbostic 91052891Sbostic /* 91152891Sbostic * Generic register access 91252891Sbostic */ 91352891Sbostic void 91452891Sbostic bt459_select_reg(regs, regno) 91552891Sbostic bt459_regmap_t *regs; 91652891Sbostic { 91752891Sbostic regs->addr_lo = regno; 91852891Sbostic regs->addr_hi = regno >> 8; 91952891Sbostic MachEmptyWriteBuffer(); 92052891Sbostic } 92152891Sbostic 92252891Sbostic void 92352891Sbostic bt459_write_reg(regs, regno, val) 92452891Sbostic bt459_regmap_t *regs; 92552891Sbostic { 92652891Sbostic regs->addr_lo = regno; 92752891Sbostic regs->addr_hi = regno >> 8; 92852891Sbostic MachEmptyWriteBuffer(); 92952891Sbostic regs->addr_reg = val; 93052891Sbostic MachEmptyWriteBuffer(); 93152891Sbostic } 93252891Sbostic 93352891Sbostic unsigned char 93452891Sbostic bt459_read_reg(regs, regno) 93552891Sbostic bt459_regmap_t *regs; 93652891Sbostic { 93752891Sbostic regs->addr_lo = regno; 93852891Sbostic regs->addr_hi = regno >> 8; 93952891Sbostic MachEmptyWriteBuffer(); 94052891Sbostic return regs->addr_reg; 94152891Sbostic } 94252891Sbostic 94352891Sbostic #ifdef DEBUG 94452891Sbostic bt459_print_colormap(regs) 94552891Sbostic bt459_regmap_t *regs; 94652891Sbostic { 94752891Sbostic register int i; 94852891Sbostic 94952891Sbostic bt459_select_reg(regs, 0); 95052891Sbostic for (i = 0; i < 256; i++) { 95152891Sbostic register unsigned red, green, blue; 95252891Sbostic 95352891Sbostic red = regs->addr_cmap; 95452891Sbostic green = regs->addr_cmap; 95552891Sbostic blue = regs->addr_cmap; 95652891Sbostic printf("%x->[x%x x%x x%x]\n", i, red, green, blue); 95752891Sbostic } 95852891Sbostic } 95952891Sbostic #endif 96052891Sbostic 96152891Sbostic /* 96252891Sbostic * Test to see if device is present. 96352891Sbostic * Return true if found and initialized ok. 96452891Sbostic */ 96552891Sbostic cfb_init(cp) 96652891Sbostic register struct pmax_ctlr *cp; 96752891Sbostic { 96852891Sbostic bt459_regmap_t *regs; 96952891Sbostic 97052891Sbostic /* check for no frame buffer */ 97152891Sbostic if (badaddr(cp->pmax_addr, 4)) 97252891Sbostic return (0); 97352891Sbostic 97452891Sbostic fb_addr = (unsigned)cp->pmax_addr + CFB_OFFSET_VRAM; 97552891Sbostic planemask_addr = 0; /* XXX */ 97652891Sbostic regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 97752891Sbostic 97852891Sbostic if (bt459_read_reg(regs, BT459_REG_ID) != 0x4a) 97952891Sbostic return (0); 98052891Sbostic 98152891Sbostic *(int *)(fb_addr + CFB_OFFSET_RESET) = 0; /* force chip reset */ 98252891Sbostic DELAY(2000); /* ???? check right time on specs! ???? */ 98352891Sbostic 98452891Sbostic /* use 4:1 input mux */ 98552891Sbostic bt459_write_reg(regs, BT459_REG_CMD0, 0x40); 98652891Sbostic 98752891Sbostic /* no zooming, no panning */ 98852891Sbostic bt459_write_reg(regs, BT459_REG_CMD1, 0x00); 98952891Sbostic 99052891Sbostic /* 99152891Sbostic * signature test, X-windows cursor, no overlays, SYNC* PLL, 99252891Sbostic * normal RAM select, 7.5 IRE pedestal, do sync 99352891Sbostic */ 99452891Sbostic bt459_write_reg(regs, BT459_REG_CMD2, 0xc2); 99552891Sbostic 99652891Sbostic /* get all pixel bits */ 99752891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 99852891Sbostic 99952891Sbostic /* no blinking */ 100052891Sbostic bt459_write_reg(regs, BT459_REG_PBM, 0x00); 100152891Sbostic 100252891Sbostic /* no overlay */ 100352891Sbostic bt459_write_reg(regs, BT459_REG_ORM, 0x00); 100452891Sbostic 100552891Sbostic /* no overlay blink */ 100652891Sbostic bt459_write_reg(regs, BT459_REG_OBM, 0x00); 100752891Sbostic 100852891Sbostic /* no interleave, no underlay */ 100952891Sbostic bt459_write_reg(regs, BT459_REG_ILV, 0x00); 101052891Sbostic 101152891Sbostic /* normal operation, no signature analysis */ 101252891Sbostic bt459_write_reg(regs, BT459_REG_TEST, 0x00); 101352891Sbostic 101452891Sbostic /* 101552891Sbostic * no blinking, 1bit cross hair, XOR reg&crosshair, 101652891Sbostic * no crosshair on either plane 0 or 1, 101752891Sbostic * regular cursor on both planes. 101852891Sbostic */ 101952891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 102052891Sbostic 102152891Sbostic /* home cursor */ 102252891Sbostic bt459_write_reg(regs, BT459_REG_CXLO, 0x00); 102352891Sbostic bt459_write_reg(regs, BT459_REG_CXHI, 0x00); 102452891Sbostic bt459_write_reg(regs, BT459_REG_CYLO, 0x00); 102552891Sbostic bt459_write_reg(regs, BT459_REG_CYHI, 0x00); 102652891Sbostic 102752891Sbostic /* no crosshair window */ 102852891Sbostic bt459_write_reg(regs, BT459_REG_WXLO, 0x00); 102952891Sbostic bt459_write_reg(regs, BT459_REG_WXHI, 0x00); 103052891Sbostic bt459_write_reg(regs, BT459_REG_WYLO, 0x00); 103152891Sbostic bt459_write_reg(regs, BT459_REG_WYHI, 0x00); 103252891Sbostic bt459_write_reg(regs, BT459_REG_WWLO, 0x00); 103352891Sbostic bt459_write_reg(regs, BT459_REG_WWHI, 0x00); 103452891Sbostic bt459_write_reg(regs, BT459_REG_WHLO, 0x00); 103552891Sbostic bt459_write_reg(regs, BT459_REG_WHHI, 0x00); 103652891Sbostic 103752891Sbostic /* 103852891Sbostic * Initialize screen info. 103952891Sbostic */ 104052891Sbostic pmu.scrInfo.max_row = MAX_ROW; 104152891Sbostic pmu.scrInfo.max_col = MAX_COL; 104252891Sbostic pmu.scrInfo.max_x = 1024; 104352891Sbostic pmu.scrInfo.max_y = 864; 104452891Sbostic pmu.scrInfo.max_cur_x = 1023; 104552891Sbostic pmu.scrInfo.max_cur_y = 863; 104652891Sbostic pmu.scrInfo.version = 11; 104752891Sbostic pmu.scrInfo.mthreshold = 4; 104852891Sbostic pmu.scrInfo.mscale = 2; 104952891Sbostic pmu.scrInfo.min_cur_x = 0; 105052891Sbostic pmu.scrInfo.min_cur_y = 0; 105152891Sbostic pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 105252891Sbostic pmu.scrInfo.qe.eSize = PM_MAXEVQ; 105352891Sbostic pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 105452891Sbostic pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 105552891Sbostic pmu.scrInfo.qe.tcNext = 0; 105652891Sbostic 105752891Sbostic /* 105852891Sbostic * Initialize the color map, the screen, and the mouse. 105952891Sbostic */ 106052891Sbostic InitColorMap(); 106152891Sbostic ScreenInit(); 106252891Sbostic Scroll(); 106352891Sbostic 106452891Sbostic initialized = 1; 106552891Sbostic return (1); 106652891Sbostic } 106752891Sbostic 106852891Sbostic /* 106952891Sbostic * ---------------------------------------------------------------------------- 107052891Sbostic * 107152891Sbostic * ScreenInit -- 107252891Sbostic * 107352891Sbostic * Initialize the screen. 107452891Sbostic * 107552891Sbostic * Results: 107652891Sbostic * None. 107752891Sbostic * 107852891Sbostic * Side effects: 107952891Sbostic * The screen is initialized. 108052891Sbostic * 108152891Sbostic * ---------------------------------------------------------------------------- 108252891Sbostic */ 108352891Sbostic static void 108452891Sbostic ScreenInit() 108552891Sbostic { 108652891Sbostic 108752891Sbostic /* 108852891Sbostic * Home the cursor. 108952891Sbostic * We want an LSI terminal emulation. We want the graphics 109052891Sbostic * terminal to scroll from the bottom. So start at the bottom. 109152891Sbostic */ 109252891Sbostic row = 55; 109352891Sbostic col = 0; 109452891Sbostic 109552891Sbostic /* 109652891Sbostic * Load the cursor with the default values 109752891Sbostic * 109852891Sbostic */ 109952891Sbostic LoadCursor(defCursor); 110052891Sbostic } 110152891Sbostic 110252891Sbostic /* 110352891Sbostic * ---------------------------------------------------------------------------- 110452891Sbostic * 110552891Sbostic * LoadCursor -- 110652891Sbostic * 110752891Sbostic * Routine to load the cursor Sprite pattern. 110852891Sbostic * 110952891Sbostic * Results: 111052891Sbostic * None. 111152891Sbostic * 111252891Sbostic * Side effects: 111352891Sbostic * The cursor is loaded into the hardware cursor. 111452891Sbostic * 111552891Sbostic * ---------------------------------------------------------------------------- 111652891Sbostic */ 111752891Sbostic static void 111852891Sbostic LoadCursor(cur) 111952891Sbostic unsigned short *cur; 112052891Sbostic { 112152891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 112252891Sbostic register int i, j; 112352891Sbostic 112452891Sbostic /* 112552891Sbostic * As per specs, must run a check to see if we 112652891Sbostic * had contention. If so, re-write the cursor. 112752891Sbostic */ 112852891Sbostic for (j = 0; j < 2; j++) { 112952891Sbostic /* loop once to write */ 113052891Sbostic bt459_select_reg(regs, BT459_REG_CRAM_BASE); 113152891Sbostic for (i = 0; i < 1024; i++) { 113252891Sbostic regs->addr_reg = cur[i]; 113352891Sbostic MachEmptyWriteBuffer(); 113452891Sbostic } 113552891Sbostic 113652891Sbostic /* loop to check, if fail write again */ 113752891Sbostic bt459_select_reg(regs, BT459_REG_CRAM_BASE); 113852891Sbostic for (i = 0; i < 1024; i++) 113952891Sbostic if (regs->addr_reg != cur[i]) 114052891Sbostic break; 114152891Sbostic if (i == 1024) 114252891Sbostic break; /* all went well first shot */ 114352891Sbostic } 114452891Sbostic } 114552891Sbostic 114652891Sbostic /* 114752891Sbostic * ---------------------------------------------------------------------------- 114852891Sbostic * 114952891Sbostic * RestoreCursorColor -- 115052891Sbostic * 115152891Sbostic * Routine to restore the color of the cursor. 115252891Sbostic * 115352891Sbostic * Results: 115452891Sbostic * None. 115552891Sbostic * 115652891Sbostic * Side effects: 115752891Sbostic * None. 115852891Sbostic * 115952891Sbostic * ---------------------------------------------------------------------------- 116052891Sbostic */ 116152891Sbostic static void 116252891Sbostic RestoreCursorColor() 116352891Sbostic { 116452891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 116552891Sbostic register int i; 116652891Sbostic 116752891Sbostic bt459_select_reg(regs, BT459_REG_CCOLOR_2); 116852891Sbostic for (i = 0; i < 6; i++) { 116952891Sbostic regs->addr_reg = cursor_RGB[i]; 117052891Sbostic MachEmptyWriteBuffer(); 117152891Sbostic } 117252891Sbostic } 117352891Sbostic 117452891Sbostic /* 117552891Sbostic * ---------------------------------------------------------------------------- 117652891Sbostic * 117752891Sbostic * CursorColor -- 117852891Sbostic * 117952891Sbostic * Set the color of the cursor. 118052891Sbostic * 118152891Sbostic * Results: 118252891Sbostic * None. 118352891Sbostic * 118452891Sbostic * Side effects: 118552891Sbostic * None. 118652891Sbostic * 118752891Sbostic * ---------------------------------------------------------------------------- 118852891Sbostic */ 118952891Sbostic static void 119052891Sbostic CursorColor(color) 119152891Sbostic unsigned int color[]; 119252891Sbostic { 119352891Sbostic register int i, j; 119452891Sbostic 119552891Sbostic for (i = 0; i < 6; i++) 119652891Sbostic cursor_RGB[i] = (u_char)(color[i] >> 8); 119752891Sbostic 119852891Sbostic RestoreCursorColor(); 119952891Sbostic } 120052891Sbostic 120152891Sbostic /* 120252891Sbostic *---------------------------------------------------------------------- 120352891Sbostic * 120452891Sbostic * PosCursor -- 120552891Sbostic * 120652891Sbostic * Postion the cursor. 120752891Sbostic * 120852891Sbostic * Results: 120952891Sbostic * None. 121052891Sbostic * 121152891Sbostic * Side effects: 121252891Sbostic * None. 121352891Sbostic * 121452891Sbostic *---------------------------------------------------------------------- 121552891Sbostic */ 121652891Sbostic static void 121752891Sbostic PosCursor(x, y) 121852891Sbostic register int x, y; 121952891Sbostic { 122052891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 122152891Sbostic 122252891Sbostic if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y) 122352891Sbostic y = pmu.scrInfo.max_cur_y; 122452891Sbostic if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x) 122552891Sbostic x = pmu.scrInfo.max_cur_x; 122652891Sbostic pmu.scrInfo.cursor.x = x; /* keep track of real cursor */ 122752891Sbostic pmu.scrInfo.cursor.y = y; /* position, indep. of mouse */ 122852891Sbostic 122952891Sbostic x += 219; 123052891Sbostic y += 34; 123152891Sbostic 123252891Sbostic bt459_select_reg(regs, BT459_REG_CXLO); 123352891Sbostic regs->addr_reg = x; 123452891Sbostic MachEmptyWriteBuffer(); 123552891Sbostic regs->addr_reg = x >> 8; 123652891Sbostic MachEmptyWriteBuffer(); 123752891Sbostic regs->addr_reg = y; 123852891Sbostic MachEmptyWriteBuffer(); 123952891Sbostic regs->addr_reg = y >> 8; 124052891Sbostic MachEmptyWriteBuffer(); 124152891Sbostic } 124252891Sbostic 124352891Sbostic /* 124452891Sbostic * ---------------------------------------------------------------------------- 124552891Sbostic * 124652891Sbostic * InitColorMap -- 124752891Sbostic * 124852891Sbostic * Initialize the color map. 124952891Sbostic * 125052891Sbostic * Results: 125152891Sbostic * None. 125252891Sbostic * 125352891Sbostic * Side effects: 125452891Sbostic * The colormap is initialized appropriately. 125552891Sbostic * 125652891Sbostic * ---------------------------------------------------------------------------- 125752891Sbostic */ 125852891Sbostic static void 125952891Sbostic InitColorMap() 126052891Sbostic { 126152891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 126252891Sbostic register int i; 126352891Sbostic 126452891Sbostic bt459_select_reg(regs, 0); 126552891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 126652891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 126752891Sbostic regs->addr_cmap = 0; MachEmptyWriteBuffer(); 126852891Sbostic 126952891Sbostic for (i = 1; i < 256; i++) { 127052891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 127152891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 127252891Sbostic regs->addr_cmap = 0xff; MachEmptyWriteBuffer(); 127352891Sbostic } 127452891Sbostic 127552891Sbostic for (i = 0; i < 3; i++) { 127652891Sbostic cursor_RGB[i] = 0x00; 127752891Sbostic cursor_RGB[i + 3] = 0xff; 127852891Sbostic } 127952891Sbostic RestoreCursorColor(); 128052891Sbostic } 128152891Sbostic 128252891Sbostic /* 128352891Sbostic * ---------------------------------------------------------------------------- 128452891Sbostic * 128552891Sbostic * LoadColorMap -- 128652891Sbostic * 128752891Sbostic * Load the color map. 128852891Sbostic * 128952891Sbostic * Results: 129052891Sbostic * None. 129152891Sbostic * 129252891Sbostic * Side effects: 129352891Sbostic * The color map is loaded. 129452891Sbostic * 129552891Sbostic * ---------------------------------------------------------------------------- 129652891Sbostic */ 129752891Sbostic static void 129852891Sbostic LoadColorMap(ptr) 129952891Sbostic ColorMap *ptr; 130052891Sbostic { 130152891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 130252891Sbostic 130352891Sbostic if (ptr->index > 256) 130452891Sbostic return; 130552891Sbostic 130652891Sbostic bt459_select_reg(regs, ptr->index); 130752891Sbostic 130852891Sbostic regs->addr_cmap = ptr->Entry.red; MachEmptyWriteBuffer(); 130952891Sbostic regs->addr_cmap = ptr->Entry.green; MachEmptyWriteBuffer(); 131052891Sbostic regs->addr_cmap = ptr->Entry.blue; MachEmptyWriteBuffer(); 131152891Sbostic } 131252891Sbostic 131352891Sbostic /* 131452891Sbostic * Video on/off state. 131552891Sbostic */ 131652891Sbostic struct vstate { 131752891Sbostic u_char color0[3]; /* saved color map entry zero */ 131852891Sbostic u_char off; /* TRUE if display is off */ 131952891Sbostic } vstate; 132052891Sbostic 132152891Sbostic /* 132252891Sbostic * ---------------------------------------------------------------------------- 132352891Sbostic * 132452891Sbostic * EnableVideo -- 132552891Sbostic * 132652891Sbostic * Enable the video display. 132752891Sbostic * 132852891Sbostic * Results: 132952891Sbostic * None. 133052891Sbostic * 133152891Sbostic * Side effects: 133252891Sbostic * The display is enabled. 133352891Sbostic * 133452891Sbostic * ---------------------------------------------------------------------------- 133552891Sbostic */ 133652891Sbostic static void 133752891Sbostic EnableVideo() 133852891Sbostic { 133952891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 134052891Sbostic 134152891Sbostic if (!vstate.off) 134252891Sbostic return; 134352891Sbostic 134452891Sbostic /* restore old color map entry zero */ 134552891Sbostic bt459_select_reg(regs, 0); 134652891Sbostic regs->addr_cmap = vstate.color0[0]; 134752891Sbostic MachEmptyWriteBuffer(); 134852891Sbostic regs->addr_cmap = vstate.color0[1]; 134952891Sbostic MachEmptyWriteBuffer(); 135052891Sbostic regs->addr_cmap = vstate.color0[2]; 135152891Sbostic MachEmptyWriteBuffer(); 135252891Sbostic 135352891Sbostic /* enable normal display */ 135452891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0xff); 135552891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0xc0); 135652891Sbostic 135752891Sbostic vstate.off = 0; 135852891Sbostic } 135952891Sbostic 136052891Sbostic /* 136152891Sbostic * ---------------------------------------------------------------------------- 136252891Sbostic * 136352891Sbostic * DisableVideo -- 136452891Sbostic * 136552891Sbostic * Disable the video display. 136652891Sbostic * 136752891Sbostic * Results: 136852891Sbostic * None. 136952891Sbostic * 137052891Sbostic * Side effects: 137152891Sbostic * The display is disabled. 137252891Sbostic * 137352891Sbostic * ---------------------------------------------------------------------------- 137452891Sbostic */ 137552891Sbostic static void 137652891Sbostic DisableVideo() 137752891Sbostic { 137852891Sbostic bt459_regmap_t *regs = (bt459_regmap_t *)(fb_addr + CFB_OFFSET_BT459); 137952891Sbostic 138052891Sbostic if (vstate.off) 138152891Sbostic return; 138252891Sbostic 138352891Sbostic /* save old color map entry zero */ 138452891Sbostic bt459_select_reg(regs, 0); 138552891Sbostic vstate.color0[0] = regs->addr_cmap; 138652891Sbostic vstate.color0[1] = regs->addr_cmap; 138752891Sbostic vstate.color0[2] = regs->addr_cmap; 138852891Sbostic 138952891Sbostic /* set color map entry zero to zero */ 139052891Sbostic bt459_select_reg(regs, 0); 139152891Sbostic regs->addr_cmap = 0; 139252891Sbostic MachEmptyWriteBuffer(); 139352891Sbostic regs->addr_cmap = 0; 139452891Sbostic MachEmptyWriteBuffer(); 139552891Sbostic regs->addr_cmap = 0; 139652891Sbostic MachEmptyWriteBuffer(); 139752891Sbostic 139852891Sbostic /* disable display */ 139952891Sbostic bt459_write_reg(regs, BT459_REG_PRM, 0); 140052891Sbostic bt459_write_reg(regs, BT459_REG_CCR, 0); 140152891Sbostic 140252891Sbostic vstate.off = 1; 140352891Sbostic } 140452891Sbostic #endif 1405