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