152130Smckusick /* 252130Smckusick * Copyright (c) 1992 Regents of the University of California. 352130Smckusick * All rights reserved. 452130Smckusick * 552130Smckusick * This code is derived from software contributed to Berkeley by 652130Smckusick * Ralph Campbell. 752130Smckusick * 852130Smckusick * %sccs.include.redist.c% 952130Smckusick * 10*52675Smckusick * @(#)pm.c 7.2 (Berkeley) 02/26/92 1152130Smckusick * 1252130Smckusick * devGraphics.c -- 1352130Smckusick * 1452130Smckusick * This file contains machine-dependent routines for the graphics device. 1552130Smckusick * 1652130Smckusick * Copyright (C) 1989 Digital Equipment Corporation. 1752130Smckusick * Permission to use, copy, modify, and distribute this software and 1852130Smckusick * its documentation for any purpose and without fee is hereby granted, 1952130Smckusick * provided that the above copyright notice appears in all copies. 2052130Smckusick * Digital Equipment Corporation makes no representations about the 2152130Smckusick * suitability of this software for any purpose. It is provided "as is" 2252130Smckusick * without express or implied warranty. 2352130Smckusick * 2452130Smckusick * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 2552130Smckusick * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 2652130Smckusick */ 2752130Smckusick 2852130Smckusick #include "pm.h" 2952130Smckusick #if NPM > 0 3052130Smckusick 3152130Smckusick #include "param.h" 3252130Smckusick #include "time.h" 3352130Smckusick #include "kernel.h" 3452130Smckusick #include "ioctl.h" 3552130Smckusick #include "file.h" 3652130Smckusick #include "errno.h" 3752130Smckusick #include "proc.h" 3852130Smckusick #include "mman.h" 3952130Smckusick #include "vm/vm.h" 4052130Smckusick 4152130Smckusick #include "machine/machConst.h" 4252130Smckusick #include "machine/machMon.h" 4352130Smckusick #include "machine/dc7085cons.h" 4452130Smckusick #include "machine/pmioctl.h" 4552130Smckusick #include "machine/pmreg.h" 4652130Smckusick 4752130Smckusick #include "device.h" 4852130Smckusick #include "font.c" 4952130Smckusick 5052130Smckusick /* 5152130Smckusick * Macro to translate from a time struct to milliseconds. 5252130Smckusick */ 5352130Smckusick #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) 5452130Smckusick 5552130Smckusick static u_short curReg; /* copy of PCCRegs.cmdr since it's read only */ 5652130Smckusick static int isMono; /* true if B&W frame buffer */ 5752130Smckusick static int initialized; /* true if 'probe' was successful */ 5852130Smckusick static int GraphicsOpen; /* true if the graphics device is open */ 59*52675Smckusick static struct selinfo pm_selp;/* process waiting for select */ 6052130Smckusick 6152130Smckusick /* 6252130Smckusick * These need to be mapped into user space. 6352130Smckusick */ 6452130Smckusick static struct pmuaccess { 6552130Smckusick PM_Info scrInfo; 6652130Smckusick pmEvent events[PM_MAXEVQ]; 6752130Smckusick pmTimeCoord tcs[MOTION_BUFFER_SIZE]; 6852130Smckusick } pmu; 6952130Smckusick 7052130Smckusick static u_char bg_RGB[3]; /* background color for the cursor */ 7152130Smckusick static u_char fg_RGB[3]; /* foreground color for the cursor */ 7252130Smckusick 7352130Smckusick /* 7452130Smckusick * The default cursor. 7552130Smckusick */ 7652130Smckusick unsigned short defCursor[32] = { 7752130Smckusick /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 7852130Smckusick 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 7952130Smckusick /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 8052130Smckusick 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 8152130Smckusick 8252130Smckusick }; 8352130Smckusick 8452130Smckusick /* 8552130Smckusick * Font mask bits used by Blitc(). 8652130Smckusick */ 8752130Smckusick static unsigned int fontmaskBits[16] = { 8852130Smckusick 0x00000000, 8952130Smckusick 0x00000001, 9052130Smckusick 0x00000100, 9152130Smckusick 0x00000101, 9252130Smckusick 0x00010000, 9352130Smckusick 0x00010001, 9452130Smckusick 0x00010100, 9552130Smckusick 0x00010101, 9652130Smckusick 0x01000000, 9752130Smckusick 0x01000001, 9852130Smckusick 0x01000100, 9952130Smckusick 0x01000101, 10052130Smckusick 0x01010000, 10152130Smckusick 0x01010001, 10252130Smckusick 0x01010100, 10352130Smckusick 0x01010101 10452130Smckusick }; 10552130Smckusick 10652130Smckusick /* 10752130Smckusick * Forward references. 10852130Smckusick */ 10952130Smckusick static void ScreenInit(); 11052130Smckusick static void LoadCursor(); 11152130Smckusick static void RestoreCursorColor(); 11252130Smckusick static void CursorColor(); 11352130Smckusick static void InitColorMap(); 11452130Smckusick static void VDACInit(); 11552130Smckusick static void LoadColorMap(); 11652130Smckusick static void PosCursor(); 11752130Smckusick static void Scroll(); 11852130Smckusick static void Blitc(); 11952130Smckusick 12052130Smckusick extern void dcKBDPutc(); 12152130Smckusick 12252130Smckusick int pmprobe(); 12352130Smckusick struct driver pmdriver = { 12452130Smckusick "pm", pmprobe, 0, 0, 12552130Smckusick }; 12652130Smckusick 12752130Smckusick /* 12852130Smckusick * Test to see if device is present. 12952130Smckusick * Return true if found and initialized ok. 13052130Smckusick */ 13152130Smckusick /*ARGSUSED*/ 13252130Smckusick pmprobe(cp) 13352130Smckusick register struct pmax_ctlr *cp; 13452130Smckusick { 13552130Smckusick 13652130Smckusick if (!initialized && !pminit()) 13752130Smckusick return (0); 13852130Smckusick if (isMono) 13952130Smckusick printf("pm0 (monochrome display)\n"); 14052130Smckusick else 14152130Smckusick printf("pm0 (color display)\n"); 14252130Smckusick return (1); 14352130Smckusick } 14452130Smckusick 14552130Smckusick /* 14652130Smckusick * Test to see if device is present. 14752130Smckusick * Return true if found and initialized ok. 14852130Smckusick */ 14952130Smckusick pminit() 15052130Smckusick { 15152130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 15252130Smckusick 15352130Smckusick isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO; 15452130Smckusick if (isMono) { 15552130Smckusick /* check for no frame buffer */ 15652130Smckusick if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4)) 15752130Smckusick return (0); 15852130Smckusick } 15952130Smckusick 16052130Smckusick /* 16152130Smckusick * Initialize the screen. 16252130Smckusick */ 16352130Smckusick #ifdef notdef 16452130Smckusick DELAY(100000); /* why? */ 16552130Smckusick #endif 16652130Smckusick pcc->cmdr = PCC_FOPB | PCC_VBHI; 16752130Smckusick 16852130Smckusick /* 16952130Smckusick * Initialize the cursor register. 17052130Smckusick */ 17152130Smckusick pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB; 17252130Smckusick 17352130Smckusick /* 17452130Smckusick * Initialize screen info. 17552130Smckusick */ 17652130Smckusick pmu.scrInfo.max_row = 56; 17752130Smckusick pmu.scrInfo.max_col = 80; 17852130Smckusick pmu.scrInfo.max_x = 1024; 17952130Smckusick pmu.scrInfo.max_y = 864; 18052130Smckusick pmu.scrInfo.max_cur_x = 1023; 18152130Smckusick pmu.scrInfo.max_cur_y = 863; 18252130Smckusick pmu.scrInfo.version = 11; 18352130Smckusick pmu.scrInfo.mthreshold = 4; 18452130Smckusick pmu.scrInfo.mscale = 2; 18552130Smckusick pmu.scrInfo.min_cur_x = -15; 18652130Smckusick pmu.scrInfo.min_cur_y = -15; 18752130Smckusick pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 18852130Smckusick pmu.scrInfo.qe.eSize = PM_MAXEVQ; 18952130Smckusick pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 19052130Smckusick pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 19152130Smckusick pmu.scrInfo.qe.tcNext = 0; 19252130Smckusick 19352130Smckusick /* 19452130Smckusick * Initialize the color map, the screen, and the mouse. 19552130Smckusick */ 19652130Smckusick InitColorMap(); 19752130Smckusick ScreenInit(); 19852130Smckusick Scroll(); 19952130Smckusick 20052130Smckusick initialized = 1; 20152130Smckusick return (1); 20252130Smckusick } 20352130Smckusick 20452130Smckusick /* 20552130Smckusick * ---------------------------------------------------------------------------- 20652130Smckusick * 20752130Smckusick * ScreenInit -- 20852130Smckusick * 20952130Smckusick * Initialize the screen. 21052130Smckusick * 21152130Smckusick * Results: 21252130Smckusick * None. 21352130Smckusick * 21452130Smckusick * Side effects: 21552130Smckusick * The screen is initialized. 21652130Smckusick * 21752130Smckusick * ---------------------------------------------------------------------------- 21852130Smckusick */ 21952130Smckusick static void 22052130Smckusick ScreenInit() 22152130Smckusick { 22252130Smckusick 22352130Smckusick /* 22452130Smckusick * Home the cursor. 22552130Smckusick * We want an LSI terminal emulation. We want the graphics 22652130Smckusick * terminal to scroll from the bottom. So start at the bottom. 22752130Smckusick */ 22852130Smckusick pmu.scrInfo.row = 55; 22952130Smckusick pmu.scrInfo.col = 0; 23052130Smckusick 23152130Smckusick /* 23252130Smckusick * Load the cursor with the default values 23352130Smckusick * 23452130Smckusick */ 23552130Smckusick LoadCursor(defCursor); 23652130Smckusick } 23752130Smckusick 23852130Smckusick /* 23952130Smckusick * ---------------------------------------------------------------------------- 24052130Smckusick * 24152130Smckusick * LoadCursor -- 24252130Smckusick * 24352130Smckusick * Routine to load the cursor Sprite pattern. 24452130Smckusick * 24552130Smckusick * Results: 24652130Smckusick * None. 24752130Smckusick * 24852130Smckusick * Side effects: 24952130Smckusick * The cursor is loaded into the hardware cursor. 25052130Smckusick * 25152130Smckusick * ---------------------------------------------------------------------------- 25252130Smckusick */ 25352130Smckusick static void 25452130Smckusick LoadCursor(cur) 25552130Smckusick unsigned short *cur; 25652130Smckusick { 25752130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 25852130Smckusick register int i; 25952130Smckusick 26052130Smckusick curReg |= PCC_LODSA; 26152130Smckusick pcc->cmdr = curReg; 26252130Smckusick for (i = 0; i < 32; i++) { 26352130Smckusick pcc->memory = cur[i]; 26452130Smckusick MachEmptyWriteBuffer(); 26552130Smckusick } 26652130Smckusick curReg &= ~PCC_LODSA; 26752130Smckusick pcc->cmdr = curReg; 26852130Smckusick } 26952130Smckusick 27052130Smckusick /* 27152130Smckusick * ---------------------------------------------------------------------------- 27252130Smckusick * 27352130Smckusick * RestoreCursorColor -- 27452130Smckusick * 27552130Smckusick * Routine to restore the color of the cursor. 27652130Smckusick * 27752130Smckusick * Results: 27852130Smckusick * None. 27952130Smckusick * 28052130Smckusick * Side effects: 28152130Smckusick * None. 28252130Smckusick * 28352130Smckusick * ---------------------------------------------------------------------------- 28452130Smckusick */ 28552130Smckusick static void 28652130Smckusick RestoreCursorColor() 28752130Smckusick { 28852130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 28952130Smckusick register int i; 29052130Smckusick 29152130Smckusick vdac->overWA = 0x04; 29252130Smckusick MachEmptyWriteBuffer(); 29352130Smckusick for (i = 0; i < 3; i++) { 29452130Smckusick vdac->over = bg_RGB[i]; 29552130Smckusick MachEmptyWriteBuffer(); 29652130Smckusick } 29752130Smckusick 29852130Smckusick vdac->overWA = 0x08; 29952130Smckusick MachEmptyWriteBuffer(); 30052130Smckusick vdac->over = 0x00; 30152130Smckusick MachEmptyWriteBuffer(); 30252130Smckusick vdac->over = 0x00; 30352130Smckusick MachEmptyWriteBuffer(); 30452130Smckusick vdac->over = 0x7f; 30552130Smckusick MachEmptyWriteBuffer(); 30652130Smckusick 30752130Smckusick vdac->overWA = 0x0c; 30852130Smckusick MachEmptyWriteBuffer(); 30952130Smckusick for (i = 0; i < 3; i++) { 31052130Smckusick vdac->over = fg_RGB[i]; 31152130Smckusick MachEmptyWriteBuffer(); 31252130Smckusick } 31352130Smckusick } 31452130Smckusick 31552130Smckusick /* 31652130Smckusick * ---------------------------------------------------------------------------- 31752130Smckusick * 31852130Smckusick * CursorColor -- 31952130Smckusick * 32052130Smckusick * Set the color of the cursor. 32152130Smckusick * 32252130Smckusick * Results: 32352130Smckusick * None. 32452130Smckusick * 32552130Smckusick * Side effects: 32652130Smckusick * None. 32752130Smckusick * 32852130Smckusick * ---------------------------------------------------------------------------- 32952130Smckusick */ 33052130Smckusick static void 33152130Smckusick CursorColor(color) 33252130Smckusick unsigned int color[]; 33352130Smckusick { 33452130Smckusick register int i, j; 33552130Smckusick 33652130Smckusick for (i = 0; i < 3; i++) 33752130Smckusick bg_RGB[i] = (u_char)(color[i] >> 8); 33852130Smckusick 33952130Smckusick for (i = 3, j = 0; i < 6; i++, j++) 34052130Smckusick fg_RGB[j] = (u_char)(color[i] >> 8); 34152130Smckusick 34252130Smckusick RestoreCursorColor(); 34352130Smckusick } 34452130Smckusick 34552130Smckusick /* 34652130Smckusick * ---------------------------------------------------------------------------- 34752130Smckusick * 34852130Smckusick * InitColorMap -- 34952130Smckusick * 35052130Smckusick * Initialize the color map. 35152130Smckusick * 35252130Smckusick * Results: 35352130Smckusick * None. 35452130Smckusick * 35552130Smckusick * Side effects: 35652130Smckusick * The colormap is initialized appropriately whether it is color or 35752130Smckusick * monochrome. 35852130Smckusick * 35952130Smckusick * ---------------------------------------------------------------------------- 36052130Smckusick */ 36152130Smckusick static void 36252130Smckusick InitColorMap() 36352130Smckusick { 36452130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 36552130Smckusick register int i; 36652130Smckusick 36752130Smckusick *(char *)MACH_PLANE_MASK_ADDR = 0xff; 36852130Smckusick MachEmptyWriteBuffer(); 36952130Smckusick 37052130Smckusick if (isMono) { 37152130Smckusick vdac->mapWA = 0; MachEmptyWriteBuffer(); 37252130Smckusick for (i = 0; i < 256; i++) { 37352130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 37452130Smckusick MachEmptyWriteBuffer(); 37552130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 37652130Smckusick MachEmptyWriteBuffer(); 37752130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 37852130Smckusick MachEmptyWriteBuffer(); 37952130Smckusick } 38052130Smckusick } else { 38152130Smckusick vdac->mapWA = 0; MachEmptyWriteBuffer(); 38252130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 38352130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 38452130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 38552130Smckusick 38652130Smckusick for (i = 1; i < 256; i++) { 38752130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 38852130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 38952130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 39052130Smckusick } 39152130Smckusick } 39252130Smckusick 39352130Smckusick for (i = 0; i < 3; i++) { 39452130Smckusick bg_RGB[i] = 0x00; 39552130Smckusick fg_RGB[i] = 0xff; 39652130Smckusick } 39752130Smckusick RestoreCursorColor(); 39852130Smckusick } 39952130Smckusick 40052130Smckusick /* 40152130Smckusick * ---------------------------------------------------------------------------- 40252130Smckusick * 40352130Smckusick * VDACInit -- 40452130Smckusick * 40552130Smckusick * Initialize the VDAC. 40652130Smckusick * 40752130Smckusick * Results: 40852130Smckusick * None. 40952130Smckusick * 41052130Smckusick * Side effects: 41152130Smckusick * None. 41252130Smckusick * 41352130Smckusick * ---------------------------------------------------------------------------- 41452130Smckusick */ 41552130Smckusick static void 41652130Smckusick VDACInit() 41752130Smckusick { 41852130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 41952130Smckusick 42052130Smckusick /* 42152130Smckusick * 42252130Smckusick * Initialize the VDAC 42352130Smckusick */ 42452130Smckusick vdac->overWA = 0x04; MachEmptyWriteBuffer(); 42552130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 42652130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 42752130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 42852130Smckusick vdac->overWA = 0x08; MachEmptyWriteBuffer(); 42952130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 43052130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 43152130Smckusick vdac->over = 0x7f; MachEmptyWriteBuffer(); 43252130Smckusick vdac->overWA = 0x0c; MachEmptyWriteBuffer(); 43352130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 43452130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 43552130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 43652130Smckusick } 43752130Smckusick 43852130Smckusick /* 43952130Smckusick * ---------------------------------------------------------------------------- 44052130Smckusick * 44152130Smckusick * LoadColorMap -- 44252130Smckusick * 44352130Smckusick * Load the color map. 44452130Smckusick * 44552130Smckusick * Results: 44652130Smckusick * None. 44752130Smckusick * 44852130Smckusick * Side effects: 44952130Smckusick * The color map is loaded. 45052130Smckusick * 45152130Smckusick * ---------------------------------------------------------------------------- 45252130Smckusick */ 45352130Smckusick static void 45452130Smckusick LoadColorMap(ptr) 45552130Smckusick ColorMap *ptr; 45652130Smckusick { 45752130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 45852130Smckusick 45952130Smckusick if (ptr->index > 256) 46052130Smckusick return; 46152130Smckusick 46252130Smckusick vdac->mapWA = ptr->index; MachEmptyWriteBuffer(); 46352130Smckusick vdac->map = ptr->Entry.red; MachEmptyWriteBuffer(); 46452130Smckusick vdac->map = ptr->Entry.green; MachEmptyWriteBuffer(); 46552130Smckusick vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer(); 46652130Smckusick } 46752130Smckusick 46852130Smckusick /* 46952130Smckusick *---------------------------------------------------------------------- 47052130Smckusick * 47152130Smckusick * pmKbdEvent -- 47252130Smckusick * 47352130Smckusick * Process a received character. 47452130Smckusick * 47552130Smckusick * Results: 47652130Smckusick * None. 47752130Smckusick * 47852130Smckusick * Side effects: 47952130Smckusick * Events added to the queue. 48052130Smckusick * 48152130Smckusick *---------------------------------------------------------------------- 48252130Smckusick */ 48352130Smckusick void 48452130Smckusick pmKbdEvent(ch) 48552130Smckusick int ch; 48652130Smckusick { 48752130Smckusick register pmEvent *eventPtr; 48852130Smckusick int i; 48952130Smckusick 49052130Smckusick if (!GraphicsOpen) 49152130Smckusick return; 49252130Smckusick 49352130Smckusick /* 49452130Smckusick * See if there is room in the queue. 49552130Smckusick */ 49652130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 49752130Smckusick if (i == pmu.scrInfo.qe.eHead) 49852130Smckusick return; 49952130Smckusick 50052130Smckusick /* 50152130Smckusick * Add the event to the queue. 50252130Smckusick */ 50352130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 50452130Smckusick eventPtr->type = BUTTON_RAW_TYPE; 50552130Smckusick eventPtr->device = KEYBOARD_DEVICE; 50652130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 50752130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 50852130Smckusick eventPtr->time = TO_MS(time); 50952130Smckusick eventPtr->key = ch; 51052130Smckusick pmu.scrInfo.qe.eTail = i; 511*52675Smckusick selwakeup(&pm_selp); 51252130Smckusick } 51352130Smckusick 51452130Smckusick /* 51552130Smckusick *---------------------------------------------------------------------- 51652130Smckusick * 51752130Smckusick * pmMouseEvent -- 51852130Smckusick * 51952130Smckusick * Process a mouse event. 52052130Smckusick * 52152130Smckusick * Results: 52252130Smckusick * None. 52352130Smckusick * 52452130Smckusick * Side effects: 52552130Smckusick * An event is added to the event queue. 52652130Smckusick * 52752130Smckusick *---------------------------------------------------------------------- 52852130Smckusick */ 52952130Smckusick void 53052130Smckusick pmMouseEvent(newRepPtr) 53152130Smckusick register MouseReport *newRepPtr; 53252130Smckusick { 53352130Smckusick unsigned milliSec; 53452130Smckusick int i; 53552130Smckusick pmEvent *eventPtr; 53652130Smckusick 53752130Smckusick if (!GraphicsOpen) 53852130Smckusick return; 53952130Smckusick 54052130Smckusick milliSec = TO_MS(time); 54152130Smckusick 54252130Smckusick /* 54352130Smckusick * Check to see if we have to accelerate the mouse 54452130Smckusick */ 54552130Smckusick if (pmu.scrInfo.mscale >= 0) { 54652130Smckusick if (newRepPtr->dx >= pmu.scrInfo.mthreshold) { 54752130Smckusick newRepPtr->dx += 54852130Smckusick (newRepPtr->dx - pmu.scrInfo.mthreshold) * 54952130Smckusick pmu.scrInfo.mscale; 55052130Smckusick } 55152130Smckusick if (newRepPtr->dy >= pmu.scrInfo.mthreshold) { 55252130Smckusick newRepPtr->dy += 55352130Smckusick (newRepPtr->dy - pmu.scrInfo.mthreshold) * 55452130Smckusick pmu.scrInfo.mscale; 55552130Smckusick } 55652130Smckusick } 55752130Smckusick 55852130Smckusick /* 55952130Smckusick * Update mouse position 56052130Smckusick */ 56152130Smckusick if (newRepPtr->state & MOUSE_X_SIGN) { 56252130Smckusick pmu.scrInfo.mouse.x += newRepPtr->dx; 56352130Smckusick if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x) 56452130Smckusick pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x; 56552130Smckusick } else { 56652130Smckusick pmu.scrInfo.mouse.x -= newRepPtr->dx; 56752130Smckusick if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x) 56852130Smckusick pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x; 56952130Smckusick } 57052130Smckusick if (newRepPtr->state & MOUSE_Y_SIGN) { 57152130Smckusick pmu.scrInfo.mouse.y -= newRepPtr->dy; 57252130Smckusick if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y) 57352130Smckusick pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y; 57452130Smckusick } else { 57552130Smckusick pmu.scrInfo.mouse.y += newRepPtr->dy; 57652130Smckusick if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y) 57752130Smckusick pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y; 57852130Smckusick } 57952130Smckusick 58052130Smckusick /* 58152130Smckusick * Move the hardware cursor. 58252130Smckusick */ 58352130Smckusick PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 58452130Smckusick 58552130Smckusick /* 58652130Smckusick * Store the motion event in the motion buffer. 58752130Smckusick */ 58852130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec; 58952130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x; 59052130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y; 59152130Smckusick if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE) 59252130Smckusick pmu.scrInfo.qe.tcNext = 0; 59352130Smckusick if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom && 59452130Smckusick pmu.scrInfo.mouse.y >= pmu.scrInfo.mbox.top && 59552130Smckusick pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right && 59652130Smckusick pmu.scrInfo.mouse.x >= pmu.scrInfo.mbox.left) 59752130Smckusick return; 59852130Smckusick 59952130Smckusick pmu.scrInfo.mbox.bottom = 0; 60052130Smckusick if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead) 60152130Smckusick return; 60252130Smckusick 60352130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1); 60452130Smckusick if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && 60552130Smckusick (i != pmu.scrInfo.qe.eHead)) { 60652130Smckusick pmEvent *eventPtr; 60752130Smckusick 60852130Smckusick eventPtr = &pmu.events[i]; 60952130Smckusick if (eventPtr->type == MOTION_TYPE) { 61052130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 61152130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 61252130Smckusick eventPtr->time = milliSec; 61352130Smckusick eventPtr->device = MOUSE_DEVICE; 61452130Smckusick return; 61552130Smckusick } 61652130Smckusick } 61752130Smckusick /* 61852130Smckusick * Put event into queue and wakeup any waiters. 61952130Smckusick */ 62052130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 62152130Smckusick eventPtr->type = MOTION_TYPE; 62252130Smckusick eventPtr->time = milliSec; 62352130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 62452130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 62552130Smckusick eventPtr->device = MOUSE_DEVICE; 62652130Smckusick pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 627*52675Smckusick selwakeup(&pm_selp); 62852130Smckusick } 62952130Smckusick 63052130Smckusick /* 63152130Smckusick *---------------------------------------------------------------------- 63252130Smckusick * 63352130Smckusick * pmMouseButtons -- 63452130Smckusick * 63552130Smckusick * Process mouse buttons. 63652130Smckusick * 63752130Smckusick * Results: 63852130Smckusick * None. 63952130Smckusick * 64052130Smckusick * Side effects: 64152130Smckusick * None. 64252130Smckusick * 64352130Smckusick *---------------------------------------------------------------------- 64452130Smckusick */ 64552130Smckusick void 64652130Smckusick pmMouseButtons(newRepPtr) 64752130Smckusick MouseReport *newRepPtr; 64852130Smckusick { 64952130Smckusick static char temp, oldSwitch, newSwitch; 65052130Smckusick int i, j; 65152130Smckusick pmEvent *eventPtr; 65252130Smckusick static MouseReport lastRep; 65352130Smckusick 65452130Smckusick if (!GraphicsOpen) 65552130Smckusick return; 65652130Smckusick 65752130Smckusick newSwitch = newRepPtr->state & 0x07; 65852130Smckusick oldSwitch = lastRep.state & 0x07; 65952130Smckusick 66052130Smckusick temp = oldSwitch ^ newSwitch; 66152130Smckusick if (temp == 0) 66252130Smckusick return; 66352130Smckusick for (j = 1; j < 8; j <<= 1) { 66452130Smckusick if ((j & temp) == 0) 66552130Smckusick continue; 66652130Smckusick 66752130Smckusick /* 66852130Smckusick * Check for room in the queue 66952130Smckusick */ 67052130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail+1); 67152130Smckusick if (i == pmu.scrInfo.qe.eHead) 67252130Smckusick return; 67352130Smckusick 67452130Smckusick /* 67552130Smckusick * Put event into queue. 67652130Smckusick */ 67752130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 67852130Smckusick 67952130Smckusick switch (j) { 68052130Smckusick case RIGHT_BUTTON: 68152130Smckusick eventPtr->key = EVENT_RIGHT_BUTTON; 68252130Smckusick break; 68352130Smckusick 68452130Smckusick case MIDDLE_BUTTON: 68552130Smckusick eventPtr->key = EVENT_MIDDLE_BUTTON; 68652130Smckusick break; 68752130Smckusick 68852130Smckusick case LEFT_BUTTON: 68952130Smckusick eventPtr->key = EVENT_LEFT_BUTTON; 69052130Smckusick } 69152130Smckusick if (newSwitch & j) 69252130Smckusick eventPtr->type = BUTTON_DOWN_TYPE; 69352130Smckusick else 69452130Smckusick eventPtr->type = BUTTON_UP_TYPE; 69552130Smckusick eventPtr->device = MOUSE_DEVICE; 69652130Smckusick 69752130Smckusick eventPtr->time = TO_MS(time); 69852130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 69952130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 70052130Smckusick } 70152130Smckusick pmu.scrInfo.qe.eTail = i; 702*52675Smckusick selwakeup(&pm_selp); 70352130Smckusick 70452130Smckusick lastRep = *newRepPtr; 70552130Smckusick pmu.scrInfo.mswitches = newSwitch; 70652130Smckusick } 70752130Smckusick 70852130Smckusick /* 70952130Smckusick *---------------------------------------------------------------------- 71052130Smckusick * 71152130Smckusick * PosCursor -- 71252130Smckusick * 71352130Smckusick * Postion the cursor. 71452130Smckusick * 71552130Smckusick * Results: 71652130Smckusick * None. 71752130Smckusick * 71852130Smckusick * Side effects: 71952130Smckusick * None. 72052130Smckusick * 72152130Smckusick *---------------------------------------------------------------------- 72252130Smckusick */ 72352130Smckusick static void 72452130Smckusick PosCursor(x, y) 72552130Smckusick register int x, y; 72652130Smckusick { 72752130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 72852130Smckusick 72952130Smckusick if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y) 73052130Smckusick y = pmu.scrInfo.max_cur_y; 73152130Smckusick if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x) 73252130Smckusick x = pmu.scrInfo.max_cur_x; 73352130Smckusick pmu.scrInfo.cursor.x = x; /* keep track of real cursor */ 73452130Smckusick pmu.scrInfo.cursor.y = y; /* position, indep. of mouse */ 73552130Smckusick pcc->xpos = PCC_X_OFFSET + x; 73652130Smckusick pcc->ypos = PCC_Y_OFFSET + y; 73752130Smckusick } 73852130Smckusick 73952130Smckusick /* 74052130Smckusick *---------------------------------------------------------------------- 74152130Smckusick * 74252130Smckusick * Scroll -- 74352130Smckusick * 74452130Smckusick * Scroll the screen. 74552130Smckusick * 74652130Smckusick * Results: 74752130Smckusick * None. 74852130Smckusick * 74952130Smckusick * Side effects: 75052130Smckusick * None. 75152130Smckusick * 75252130Smckusick *---------------------------------------------------------------------- 75352130Smckusick */ 75452130Smckusick static void 75552130Smckusick Scroll() 75652130Smckusick { 75752130Smckusick register int *dest, *src; 75852130Smckusick register int *end; 75952130Smckusick register int temp0, temp1, temp2, temp3; 76052130Smckusick register int i, scanInc, lineCount; 76152130Smckusick int line; 76252130Smckusick 76352130Smckusick /* 76452130Smckusick * If the mouse is on we don't scroll so that the bit map remains sane. 76552130Smckusick */ 76652130Smckusick if (GraphicsOpen) { 76752130Smckusick pmu.scrInfo.row = 0; 76852130Smckusick return; 76952130Smckusick } 77052130Smckusick 77152130Smckusick /* 77252130Smckusick * The following is an optimization to cause the scrolling 77352130Smckusick * of text to be memory limited. Basically the writebuffer is 77452130Smckusick * 4 words (32 bits ea.) long so to achieve maximum speed we 77552130Smckusick * read and write in multiples of 4 words. We also limit the 77652130Smckusick * size to be 80 characters for more speed. 77752130Smckusick */ 77852130Smckusick if (isMono) { 77952130Smckusick lineCount = 5; 78052130Smckusick line = 1920 * 2; 78152130Smckusick scanInc = 44; 78252130Smckusick } else { 78352130Smckusick lineCount = 40; 78452130Smckusick scanInc = 96; 78552130Smckusick line = 1920 * 8; 78652130Smckusick } 78752130Smckusick src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line); 78852130Smckusick dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR); 78952130Smckusick end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line); 79052130Smckusick do { 79152130Smckusick i = 0; 79252130Smckusick do { 79352130Smckusick temp0 = src[0]; 79452130Smckusick temp1 = src[1]; 79552130Smckusick temp2 = src[2]; 79652130Smckusick temp3 = src[3]; 79752130Smckusick dest[0] = temp0; 79852130Smckusick dest[1] = temp1; 79952130Smckusick dest[2] = temp2; 80052130Smckusick dest[3] = temp3; 80152130Smckusick dest += 4; 80252130Smckusick src += 4; 80352130Smckusick i++; 80452130Smckusick } while (i < lineCount); 80552130Smckusick src += scanInc; 80652130Smckusick dest += scanInc; 80752130Smckusick } while (src < end); 80852130Smckusick 80952130Smckusick /* 81052130Smckusick * Now zero out the last two lines 81152130Smckusick */ 81252130Smckusick bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (pmu.scrInfo.row * line), 81352130Smckusick 3 * line); 81452130Smckusick } 81552130Smckusick 81652130Smckusick /* 81752130Smckusick *---------------------------------------------------------------------- 81852130Smckusick * 81952130Smckusick * pmPutc -- 82052130Smckusick * 82152130Smckusick * Write a character to the console. 82252130Smckusick * 82352130Smckusick * Results: 82452130Smckusick * None. 82552130Smckusick * 82652130Smckusick * Side effects: 82752130Smckusick * None. 82852130Smckusick * 82952130Smckusick *---------------------------------------------------------------------- 83052130Smckusick */ 83152130Smckusick pmPutc(c) 83252130Smckusick register int c; 83352130Smckusick { 83452130Smckusick int s; 83552130Smckusick 83652130Smckusick s = splhigh(); /* in case we do any printf's at interrupt time */ 83752130Smckusick if (initialized) { 83852130Smckusick #ifdef DEBUG 83952130Smckusick /* 84052130Smckusick * If the HELP key is pressed, wait for another 84152130Smckusick * HELP key press to start/stop output. 84252130Smckusick */ 84352130Smckusick if (dcKBDGetc() == LK_HELP) { 84452130Smckusick while (dcKBDGetc() != LK_HELP) 84552130Smckusick ; 84652130Smckusick } 84752130Smckusick #endif 84852130Smckusick Blitc(c); 84952130Smckusick } else { 85052130Smckusick void (*f)() = (void (*)())MACH_MON_PUTCHAR; 85152130Smckusick 85252130Smckusick (*f)(c); 85352130Smckusick } 85452130Smckusick splx(s); 85552130Smckusick } 85652130Smckusick 85752130Smckusick /* 85852130Smckusick *---------------------------------------------------------------------- 85952130Smckusick * 86052130Smckusick * Blitc -- 86152130Smckusick * 86252130Smckusick * Write a character to the screen. 86352130Smckusick * 86452130Smckusick * Results: 86552130Smckusick * None. 86652130Smckusick * 86752130Smckusick * Side effects: 86852130Smckusick * None. 86952130Smckusick * 87052130Smckusick *---------------------------------------------------------------------- 87152130Smckusick */ 87252130Smckusick static void 87352130Smckusick Blitc(c) 87452130Smckusick register int c; 87552130Smckusick { 87652130Smckusick register char *bRow, *fRow; 87752130Smckusick register int i; 87852130Smckusick register int ote = isMono ? 256 : 1024; /* offset to table entry */ 87952130Smckusick int colMult = isMono ? 1 : 8; 88052130Smckusick 88152130Smckusick c &= 0xff; 88252130Smckusick 88352130Smckusick switch (c) { 88452130Smckusick case '\t': 88552130Smckusick for (i = 8 - (pmu.scrInfo.col & 0x7); i > 0; i--) 88652130Smckusick Blitc(' '); 88752130Smckusick break; 88852130Smckusick 88952130Smckusick case '\r': 89052130Smckusick pmu.scrInfo.col = 0; 89152130Smckusick break; 89252130Smckusick 89352130Smckusick case '\b': 89452130Smckusick pmu.scrInfo.col--; 89552130Smckusick if (pmu.scrInfo.col < 0) 89652130Smckusick pmu.scrInfo.col = 0; 89752130Smckusick break; 89852130Smckusick 89952130Smckusick case '\n': 90052130Smckusick if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row) 90152130Smckusick Scroll(); 90252130Smckusick else 90352130Smckusick pmu.scrInfo.row++; 90452130Smckusick pmu.scrInfo.col = 0; 90552130Smckusick break; 90652130Smckusick 90752130Smckusick case '\007': 90852130Smckusick dcKBDPutc(LK_RING_BELL); 90952130Smckusick break; 91052130Smckusick 91152130Smckusick default: 91252130Smckusick /* 91352130Smckusick * If the next character will wrap around then 91452130Smckusick * increment row counter or scroll screen. 91552130Smckusick */ 91652130Smckusick if (pmu.scrInfo.col >= pmu.scrInfo.max_col) { 91752130Smckusick pmu.scrInfo.col = 0; 91852130Smckusick if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row) 91952130Smckusick Scroll(); 92052130Smckusick else 92152130Smckusick pmu.scrInfo.row++; 92252130Smckusick } 92352130Smckusick /* 92452130Smckusick * 0xA1 to 0xFD are the printable characters added with 8-bit 92552130Smckusick * support. 92652130Smckusick */ 92752130Smckusick if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD) 92852130Smckusick break; 92952130Smckusick bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + 93052130Smckusick (pmu.scrInfo.row * 15 & 0x3ff) * ote + 93152130Smckusick pmu.scrInfo.col * colMult); 93252130Smckusick i = c - ' '; 93352130Smckusick /* 93452130Smckusick * This is to skip the (32) 8-bit 93552130Smckusick * control chars, as well as DEL 93652130Smckusick * and 0xA0 which aren't printable 93752130Smckusick */ 93852130Smckusick if (c > '~') 93952130Smckusick i -= 34; 94052130Smckusick i *= 15; 94152130Smckusick fRow = (char *)((int)pmFont + i); 94252130Smckusick 94352130Smckusick /* inline expansion for speed */ 94452130Smckusick if (isMono) { 94552130Smckusick *bRow = *fRow++; bRow += ote; 94652130Smckusick *bRow = *fRow++; bRow += ote; 94752130Smckusick *bRow = *fRow++; bRow += ote; 94852130Smckusick *bRow = *fRow++; bRow += ote; 94952130Smckusick *bRow = *fRow++; bRow += ote; 95052130Smckusick *bRow = *fRow++; bRow += ote; 95152130Smckusick *bRow = *fRow++; bRow += ote; 95252130Smckusick *bRow = *fRow++; bRow += ote; 95352130Smckusick *bRow = *fRow++; bRow += ote; 95452130Smckusick *bRow = *fRow++; bRow += ote; 95552130Smckusick *bRow = *fRow++; bRow += ote; 95652130Smckusick *bRow = *fRow++; bRow += ote; 95752130Smckusick *bRow = *fRow++; bRow += ote; 95852130Smckusick *bRow = *fRow++; bRow += ote; 95952130Smckusick *bRow = *fRow++; bRow += ote; 96052130Smckusick } else { 96152130Smckusick register int j; 96252130Smckusick register unsigned int *pInt; 96352130Smckusick 96452130Smckusick pInt = (unsigned int *)bRow; 96552130Smckusick for (j = 0; j < 15; j++) { 96652130Smckusick /* 96752130Smckusick * fontmaskBits converts a nibble 96852130Smckusick * (4 bytes) to a long word 96952130Smckusick * containing 4 pixels corresponding 97052130Smckusick * to each bit in the nibble. Thus 97152130Smckusick * we write two longwords for each 97252130Smckusick * byte in font. 97352130Smckusick * 97452130Smckusick * Remember the font is 8 bits wide 97552130Smckusick * and 15 bits high. 97652130Smckusick * 97752130Smckusick * We add 256 to the pointer to 97852130Smckusick * point to the pixel on the 97952130Smckusick * next scan line 98052130Smckusick * directly below the current 98152130Smckusick * pixel. 98252130Smckusick */ 98352130Smckusick pInt[0] = fontmaskBits[(*fRow) & 0xf]; 98452130Smckusick pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf]; 98552130Smckusick fRow++; 98652130Smckusick pInt += 256; 98752130Smckusick } 98852130Smckusick } 98952130Smckusick pmu.scrInfo.col++; /* increment column counter */ 99052130Smckusick } 99152130Smckusick if (!GraphicsOpen) 99252130Smckusick PosCursor(pmu.scrInfo.col * 8, pmu.scrInfo.row * 15); 99352130Smckusick } 99452130Smckusick 99552130Smckusick /*ARGSUSED*/ 99652130Smckusick pmopen(dev, flag) 99752130Smckusick dev_t dev; 99852130Smckusick int flag; 99952130Smckusick { 100052130Smckusick 100152130Smckusick if (!initialized) 100252130Smckusick return (ENXIO); 100352130Smckusick if (GraphicsOpen) 100452130Smckusick return (EBUSY); 100552130Smckusick 100652130Smckusick GraphicsOpen = 1; 100752130Smckusick if (!isMono) 100852130Smckusick InitColorMap(); 100952130Smckusick /* 101052130Smckusick * Set up event queue for later 101152130Smckusick */ 101252130Smckusick pmu.scrInfo.qe.eSize = PM_MAXEVQ; 101352130Smckusick pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 101452130Smckusick pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 101552130Smckusick pmu.scrInfo.qe.tcNext = 0; 101652130Smckusick pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 101752130Smckusick return (0); 101852130Smckusick } 101952130Smckusick 102052130Smckusick /*ARGSUSED*/ 102152130Smckusick pmclose(dev, flag) 102252130Smckusick dev_t dev; 102352130Smckusick int flag; 102452130Smckusick { 102552130Smckusick 102652130Smckusick if (!GraphicsOpen) 102752130Smckusick return (EBADF); 102852130Smckusick 102952130Smckusick GraphicsOpen = 0; 103052130Smckusick if (!isMono) 103152130Smckusick InitColorMap(); 103252130Smckusick ScreenInit(); 103352130Smckusick vmUserUnmap(); 103452130Smckusick return (0); 103552130Smckusick } 103652130Smckusick 103752130Smckusick /*ARGSUSED*/ 103852130Smckusick pmioctl(dev, cmd, data, flag) 103952130Smckusick dev_t dev; 104052130Smckusick caddr_t data; 104152130Smckusick { 104252130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 104352130Smckusick extern int dcDivertXInput; 104452130Smckusick 104552130Smckusick switch (cmd) { 104652130Smckusick case QIOCGINFO: 104752130Smckusick { 104852130Smckusick caddr_t addr; 104952130Smckusick extern caddr_t vmUserMap(); 105052130Smckusick 105152130Smckusick /* 105252130Smckusick * Map the all the data the user needs access to into 105352130Smckusick * user space. 105452130Smckusick */ 105552130Smckusick addr = vmUserMap(sizeof(pmu), (unsigned)&pmu); 105652130Smckusick if (addr == (caddr_t)0) 105752130Smckusick goto mapError; 105852130Smckusick *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo; 105952130Smckusick pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events; 106052130Smckusick pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs; 106152130Smckusick /* 106252130Smckusick * Map the plane mask into the user's address space. 106352130Smckusick */ 106452130Smckusick addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR); 106552130Smckusick if (addr == (caddr_t)0) 106652130Smckusick goto mapError; 106752130Smckusick pmu.scrInfo.planemask = (char *)addr; 106852130Smckusick /* 106952130Smckusick * Map the bitmap into the user's address space. 107052130Smckusick */ 107152130Smckusick addr = vmUserMap(isMono ? 256*1024 : 1024*1024, 107252130Smckusick (unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR); 107352130Smckusick if (addr == (caddr_t)0) 107452130Smckusick goto mapError; 107552130Smckusick pmu.scrInfo.bitmap = (char *)addr; 107652130Smckusick break; 107752130Smckusick 107852130Smckusick mapError: 107952130Smckusick vmUserUnmap(); 108052130Smckusick printf("Cannot map shared data structures\n"); 108152130Smckusick return (EIO); 108252130Smckusick } 108352130Smckusick 108452130Smckusick case QIOCPMSTATE: 108552130Smckusick /* 108652130Smckusick * Set mouse state. 108752130Smckusick */ 108852130Smckusick pmu.scrInfo.mouse = *(pmCursor *)data; 108952130Smckusick PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 109052130Smckusick break; 109152130Smckusick 109252130Smckusick case QIOCINIT: 109352130Smckusick /* 109452130Smckusick * Initialize the screen. 109552130Smckusick */ 109652130Smckusick ScreenInit(); 109752130Smckusick break; 109852130Smckusick 109952130Smckusick case QIOCKPCMD: 110052130Smckusick { 110152130Smckusick pmKpCmd *kpCmdPtr; 110252130Smckusick unsigned char *cp; 110352130Smckusick 110452130Smckusick kpCmdPtr = (pmKpCmd *)data; 110552130Smckusick if (kpCmdPtr->nbytes == 0) 110652130Smckusick kpCmdPtr->cmd |= 0x80; 110752130Smckusick if (!GraphicsOpen) 110852130Smckusick kpCmdPtr->cmd |= 1; 110952130Smckusick dcKBDPutc((int)kpCmdPtr->cmd); 111052130Smckusick cp = &kpCmdPtr->par[0]; 111152130Smckusick for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 111252130Smckusick if (kpCmdPtr->nbytes == 1) 111352130Smckusick *cp |= 0x80; 111452130Smckusick dcKBDPutc((int)*cp); 111552130Smckusick } 111652130Smckusick break; 111752130Smckusick } 111852130Smckusick 111952130Smckusick case QIOCADDR: 112052130Smckusick *(PM_Info **)data = &pmu.scrInfo; 112152130Smckusick break; 112252130Smckusick 112352130Smckusick case QIOWCURSOR: 112452130Smckusick LoadCursor((unsigned short *)data); 112552130Smckusick break; 112652130Smckusick 112752130Smckusick case QIOWCURSORCOLOR: 112852130Smckusick CursorColor((unsigned int *)data); 112952130Smckusick break; 113052130Smckusick 113152130Smckusick case QIOSETCMAP: 113252130Smckusick LoadColorMap((ColorMap *)data); 113352130Smckusick break; 113452130Smckusick 113552130Smckusick case QIOKERNLOOP: 113652130Smckusick printf("pmioctl: QIOKERNLOOP\n"); /* XXX */ 113752130Smckusick dcDivertXInput = 1; 113852130Smckusick break; 113952130Smckusick 114052130Smckusick case QIOKERNUNLOOP: 114152130Smckusick printf("pmioctl: QIOKERNUNLOOP\n"); /* XXX */ 114252130Smckusick dcDivertXInput = 0; 114352130Smckusick break; 114452130Smckusick 114552130Smckusick case QIOVIDEOON: 114652130Smckusick if (!isMono) 114752130Smckusick RestoreCursorColor(); 114852130Smckusick curReg |= PCC_ENPA; 114952130Smckusick curReg &= ~PCC_FOPB; 115052130Smckusick pcc->cmdr = curReg; 115152130Smckusick break; 115252130Smckusick 115352130Smckusick case QIOVIDEOOFF: 115452130Smckusick if (!isMono) 115552130Smckusick VDACInit(); 115652130Smckusick curReg |= PCC_FOPB; 115752130Smckusick curReg &= ~PCC_ENPA; 115852130Smckusick pcc->cmdr = curReg; 115952130Smckusick break; 116052130Smckusick 116152130Smckusick default: 116252130Smckusick printf("pm0: Unknown command %x\n", cmd); 116352130Smckusick return (EINVAL); 116452130Smckusick } 116552130Smckusick return (0); 116652130Smckusick } 116752130Smckusick 1168*52675Smckusick pmselect(dev, flag, p) 116952130Smckusick dev_t dev; 117052130Smckusick int flag; 1171*52675Smckusick struct proc *p; 117252130Smckusick { 117352130Smckusick 117452130Smckusick switch (flag) { 117552130Smckusick case FREAD: 117652130Smckusick if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail) 117752130Smckusick return (1); 1178*52675Smckusick selrecord(p, &pm_selp); 117952130Smckusick break; 118052130Smckusick } 118152130Smckusick 118252130Smckusick return (0); 118352130Smckusick } 118452130Smckusick #endif 1185