1*52130Smckusick /* 2*52130Smckusick * Copyright (c) 1992 Regents of the University of California. 3*52130Smckusick * All rights reserved. 4*52130Smckusick * 5*52130Smckusick * This code is derived from software contributed to Berkeley by 6*52130Smckusick * Ralph Campbell. 7*52130Smckusick * 8*52130Smckusick * %sccs.include.redist.c% 9*52130Smckusick * 10*52130Smckusick * @(#)pm.c 7.1 (Berkeley) 01/07/92 11*52130Smckusick * 12*52130Smckusick * devGraphics.c -- 13*52130Smckusick * 14*52130Smckusick * This file contains machine-dependent routines for the graphics device. 15*52130Smckusick * 16*52130Smckusick * Copyright (C) 1989 Digital Equipment Corporation. 17*52130Smckusick * Permission to use, copy, modify, and distribute this software and 18*52130Smckusick * its documentation for any purpose and without fee is hereby granted, 19*52130Smckusick * provided that the above copyright notice appears in all copies. 20*52130Smckusick * Digital Equipment Corporation makes no representations about the 21*52130Smckusick * suitability of this software for any purpose. It is provided "as is" 22*52130Smckusick * without express or implied warranty. 23*52130Smckusick * 24*52130Smckusick * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, 25*52130Smckusick * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; 26*52130Smckusick */ 27*52130Smckusick 28*52130Smckusick #include "pm.h" 29*52130Smckusick #if NPM > 0 30*52130Smckusick 31*52130Smckusick #include "param.h" 32*52130Smckusick #include "time.h" 33*52130Smckusick #include "kernel.h" 34*52130Smckusick #include "ioctl.h" 35*52130Smckusick #include "file.h" 36*52130Smckusick #include "errno.h" 37*52130Smckusick #include "proc.h" 38*52130Smckusick #include "mman.h" 39*52130Smckusick #include "vm/vm.h" 40*52130Smckusick 41*52130Smckusick #include "machine/machConst.h" 42*52130Smckusick #include "machine/machMon.h" 43*52130Smckusick #include "machine/dc7085cons.h" 44*52130Smckusick #include "machine/pmioctl.h" 45*52130Smckusick #include "machine/pmreg.h" 46*52130Smckusick 47*52130Smckusick #include "device.h" 48*52130Smckusick #include "font.c" 49*52130Smckusick 50*52130Smckusick /* 51*52130Smckusick * Macro to translate from a time struct to milliseconds. 52*52130Smckusick */ 53*52130Smckusick #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) 54*52130Smckusick 55*52130Smckusick static u_short curReg; /* copy of PCCRegs.cmdr since it's read only */ 56*52130Smckusick static int isMono; /* true if B&W frame buffer */ 57*52130Smckusick static int initialized; /* true if 'probe' was successful */ 58*52130Smckusick static int GraphicsOpen; /* true if the graphics device is open */ 59*52130Smckusick static struct proc *pm_selp; /* process waiting for select */ 60*52130Smckusick 61*52130Smckusick /* 62*52130Smckusick * These need to be mapped into user space. 63*52130Smckusick */ 64*52130Smckusick static struct pmuaccess { 65*52130Smckusick PM_Info scrInfo; 66*52130Smckusick pmEvent events[PM_MAXEVQ]; 67*52130Smckusick pmTimeCoord tcs[MOTION_BUFFER_SIZE]; 68*52130Smckusick } pmu; 69*52130Smckusick 70*52130Smckusick static u_char bg_RGB[3]; /* background color for the cursor */ 71*52130Smckusick static u_char fg_RGB[3]; /* foreground color for the cursor */ 72*52130Smckusick 73*52130Smckusick /* 74*52130Smckusick * The default cursor. 75*52130Smckusick */ 76*52130Smckusick unsigned short defCursor[32] = { 77*52130Smckusick /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 78*52130Smckusick 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 79*52130Smckusick /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 80*52130Smckusick 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 81*52130Smckusick 82*52130Smckusick }; 83*52130Smckusick 84*52130Smckusick /* 85*52130Smckusick * Font mask bits used by Blitc(). 86*52130Smckusick */ 87*52130Smckusick static unsigned int fontmaskBits[16] = { 88*52130Smckusick 0x00000000, 89*52130Smckusick 0x00000001, 90*52130Smckusick 0x00000100, 91*52130Smckusick 0x00000101, 92*52130Smckusick 0x00010000, 93*52130Smckusick 0x00010001, 94*52130Smckusick 0x00010100, 95*52130Smckusick 0x00010101, 96*52130Smckusick 0x01000000, 97*52130Smckusick 0x01000001, 98*52130Smckusick 0x01000100, 99*52130Smckusick 0x01000101, 100*52130Smckusick 0x01010000, 101*52130Smckusick 0x01010001, 102*52130Smckusick 0x01010100, 103*52130Smckusick 0x01010101 104*52130Smckusick }; 105*52130Smckusick 106*52130Smckusick /* 107*52130Smckusick * Forward references. 108*52130Smckusick */ 109*52130Smckusick static void ScreenInit(); 110*52130Smckusick static void LoadCursor(); 111*52130Smckusick static void RestoreCursorColor(); 112*52130Smckusick static void CursorColor(); 113*52130Smckusick static void InitColorMap(); 114*52130Smckusick static void VDACInit(); 115*52130Smckusick static void LoadColorMap(); 116*52130Smckusick static void PosCursor(); 117*52130Smckusick static void Scroll(); 118*52130Smckusick static void Blitc(); 119*52130Smckusick 120*52130Smckusick extern void dcKBDPutc(); 121*52130Smckusick 122*52130Smckusick int pmprobe(); 123*52130Smckusick struct driver pmdriver = { 124*52130Smckusick "pm", pmprobe, 0, 0, 125*52130Smckusick }; 126*52130Smckusick 127*52130Smckusick /* 128*52130Smckusick * Test to see if device is present. 129*52130Smckusick * Return true if found and initialized ok. 130*52130Smckusick */ 131*52130Smckusick /*ARGSUSED*/ 132*52130Smckusick pmprobe(cp) 133*52130Smckusick register struct pmax_ctlr *cp; 134*52130Smckusick { 135*52130Smckusick 136*52130Smckusick if (!initialized && !pminit()) 137*52130Smckusick return (0); 138*52130Smckusick if (isMono) 139*52130Smckusick printf("pm0 (monochrome display)\n"); 140*52130Smckusick else 141*52130Smckusick printf("pm0 (color display)\n"); 142*52130Smckusick return (1); 143*52130Smckusick } 144*52130Smckusick 145*52130Smckusick /* 146*52130Smckusick * Test to see if device is present. 147*52130Smckusick * Return true if found and initialized ok. 148*52130Smckusick */ 149*52130Smckusick pminit() 150*52130Smckusick { 151*52130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 152*52130Smckusick 153*52130Smckusick isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO; 154*52130Smckusick if (isMono) { 155*52130Smckusick /* check for no frame buffer */ 156*52130Smckusick if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4)) 157*52130Smckusick return (0); 158*52130Smckusick } 159*52130Smckusick 160*52130Smckusick /* 161*52130Smckusick * Initialize the screen. 162*52130Smckusick */ 163*52130Smckusick #ifdef notdef 164*52130Smckusick DELAY(100000); /* why? */ 165*52130Smckusick #endif 166*52130Smckusick pcc->cmdr = PCC_FOPB | PCC_VBHI; 167*52130Smckusick 168*52130Smckusick /* 169*52130Smckusick * Initialize the cursor register. 170*52130Smckusick */ 171*52130Smckusick pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB; 172*52130Smckusick 173*52130Smckusick /* 174*52130Smckusick * Initialize screen info. 175*52130Smckusick */ 176*52130Smckusick pmu.scrInfo.max_row = 56; 177*52130Smckusick pmu.scrInfo.max_col = 80; 178*52130Smckusick pmu.scrInfo.max_x = 1024; 179*52130Smckusick pmu.scrInfo.max_y = 864; 180*52130Smckusick pmu.scrInfo.max_cur_x = 1023; 181*52130Smckusick pmu.scrInfo.max_cur_y = 863; 182*52130Smckusick pmu.scrInfo.version = 11; 183*52130Smckusick pmu.scrInfo.mthreshold = 4; 184*52130Smckusick pmu.scrInfo.mscale = 2; 185*52130Smckusick pmu.scrInfo.min_cur_x = -15; 186*52130Smckusick pmu.scrInfo.min_cur_y = -15; 187*52130Smckusick pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 188*52130Smckusick pmu.scrInfo.qe.eSize = PM_MAXEVQ; 189*52130Smckusick pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 190*52130Smckusick pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 191*52130Smckusick pmu.scrInfo.qe.tcNext = 0; 192*52130Smckusick 193*52130Smckusick /* 194*52130Smckusick * Initialize the color map, the screen, and the mouse. 195*52130Smckusick */ 196*52130Smckusick InitColorMap(); 197*52130Smckusick ScreenInit(); 198*52130Smckusick Scroll(); 199*52130Smckusick 200*52130Smckusick initialized = 1; 201*52130Smckusick return (1); 202*52130Smckusick } 203*52130Smckusick 204*52130Smckusick /* 205*52130Smckusick * ---------------------------------------------------------------------------- 206*52130Smckusick * 207*52130Smckusick * ScreenInit -- 208*52130Smckusick * 209*52130Smckusick * Initialize the screen. 210*52130Smckusick * 211*52130Smckusick * Results: 212*52130Smckusick * None. 213*52130Smckusick * 214*52130Smckusick * Side effects: 215*52130Smckusick * The screen is initialized. 216*52130Smckusick * 217*52130Smckusick * ---------------------------------------------------------------------------- 218*52130Smckusick */ 219*52130Smckusick static void 220*52130Smckusick ScreenInit() 221*52130Smckusick { 222*52130Smckusick 223*52130Smckusick /* 224*52130Smckusick * Home the cursor. 225*52130Smckusick * We want an LSI terminal emulation. We want the graphics 226*52130Smckusick * terminal to scroll from the bottom. So start at the bottom. 227*52130Smckusick */ 228*52130Smckusick pmu.scrInfo.row = 55; 229*52130Smckusick pmu.scrInfo.col = 0; 230*52130Smckusick 231*52130Smckusick /* 232*52130Smckusick * Load the cursor with the default values 233*52130Smckusick * 234*52130Smckusick */ 235*52130Smckusick LoadCursor(defCursor); 236*52130Smckusick } 237*52130Smckusick 238*52130Smckusick /* 239*52130Smckusick * ---------------------------------------------------------------------------- 240*52130Smckusick * 241*52130Smckusick * LoadCursor -- 242*52130Smckusick * 243*52130Smckusick * Routine to load the cursor Sprite pattern. 244*52130Smckusick * 245*52130Smckusick * Results: 246*52130Smckusick * None. 247*52130Smckusick * 248*52130Smckusick * Side effects: 249*52130Smckusick * The cursor is loaded into the hardware cursor. 250*52130Smckusick * 251*52130Smckusick * ---------------------------------------------------------------------------- 252*52130Smckusick */ 253*52130Smckusick static void 254*52130Smckusick LoadCursor(cur) 255*52130Smckusick unsigned short *cur; 256*52130Smckusick { 257*52130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 258*52130Smckusick register int i; 259*52130Smckusick 260*52130Smckusick curReg |= PCC_LODSA; 261*52130Smckusick pcc->cmdr = curReg; 262*52130Smckusick for (i = 0; i < 32; i++) { 263*52130Smckusick pcc->memory = cur[i]; 264*52130Smckusick MachEmptyWriteBuffer(); 265*52130Smckusick } 266*52130Smckusick curReg &= ~PCC_LODSA; 267*52130Smckusick pcc->cmdr = curReg; 268*52130Smckusick } 269*52130Smckusick 270*52130Smckusick /* 271*52130Smckusick * ---------------------------------------------------------------------------- 272*52130Smckusick * 273*52130Smckusick * RestoreCursorColor -- 274*52130Smckusick * 275*52130Smckusick * Routine to restore the color of the cursor. 276*52130Smckusick * 277*52130Smckusick * Results: 278*52130Smckusick * None. 279*52130Smckusick * 280*52130Smckusick * Side effects: 281*52130Smckusick * None. 282*52130Smckusick * 283*52130Smckusick * ---------------------------------------------------------------------------- 284*52130Smckusick */ 285*52130Smckusick static void 286*52130Smckusick RestoreCursorColor() 287*52130Smckusick { 288*52130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 289*52130Smckusick register int i; 290*52130Smckusick 291*52130Smckusick vdac->overWA = 0x04; 292*52130Smckusick MachEmptyWriteBuffer(); 293*52130Smckusick for (i = 0; i < 3; i++) { 294*52130Smckusick vdac->over = bg_RGB[i]; 295*52130Smckusick MachEmptyWriteBuffer(); 296*52130Smckusick } 297*52130Smckusick 298*52130Smckusick vdac->overWA = 0x08; 299*52130Smckusick MachEmptyWriteBuffer(); 300*52130Smckusick vdac->over = 0x00; 301*52130Smckusick MachEmptyWriteBuffer(); 302*52130Smckusick vdac->over = 0x00; 303*52130Smckusick MachEmptyWriteBuffer(); 304*52130Smckusick vdac->over = 0x7f; 305*52130Smckusick MachEmptyWriteBuffer(); 306*52130Smckusick 307*52130Smckusick vdac->overWA = 0x0c; 308*52130Smckusick MachEmptyWriteBuffer(); 309*52130Smckusick for (i = 0; i < 3; i++) { 310*52130Smckusick vdac->over = fg_RGB[i]; 311*52130Smckusick MachEmptyWriteBuffer(); 312*52130Smckusick } 313*52130Smckusick } 314*52130Smckusick 315*52130Smckusick /* 316*52130Smckusick * ---------------------------------------------------------------------------- 317*52130Smckusick * 318*52130Smckusick * CursorColor -- 319*52130Smckusick * 320*52130Smckusick * Set the color of the cursor. 321*52130Smckusick * 322*52130Smckusick * Results: 323*52130Smckusick * None. 324*52130Smckusick * 325*52130Smckusick * Side effects: 326*52130Smckusick * None. 327*52130Smckusick * 328*52130Smckusick * ---------------------------------------------------------------------------- 329*52130Smckusick */ 330*52130Smckusick static void 331*52130Smckusick CursorColor(color) 332*52130Smckusick unsigned int color[]; 333*52130Smckusick { 334*52130Smckusick register int i, j; 335*52130Smckusick 336*52130Smckusick for (i = 0; i < 3; i++) 337*52130Smckusick bg_RGB[i] = (u_char)(color[i] >> 8); 338*52130Smckusick 339*52130Smckusick for (i = 3, j = 0; i < 6; i++, j++) 340*52130Smckusick fg_RGB[j] = (u_char)(color[i] >> 8); 341*52130Smckusick 342*52130Smckusick RestoreCursorColor(); 343*52130Smckusick } 344*52130Smckusick 345*52130Smckusick /* 346*52130Smckusick * ---------------------------------------------------------------------------- 347*52130Smckusick * 348*52130Smckusick * InitColorMap -- 349*52130Smckusick * 350*52130Smckusick * Initialize the color map. 351*52130Smckusick * 352*52130Smckusick * Results: 353*52130Smckusick * None. 354*52130Smckusick * 355*52130Smckusick * Side effects: 356*52130Smckusick * The colormap is initialized appropriately whether it is color or 357*52130Smckusick * monochrome. 358*52130Smckusick * 359*52130Smckusick * ---------------------------------------------------------------------------- 360*52130Smckusick */ 361*52130Smckusick static void 362*52130Smckusick InitColorMap() 363*52130Smckusick { 364*52130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 365*52130Smckusick register int i; 366*52130Smckusick 367*52130Smckusick *(char *)MACH_PLANE_MASK_ADDR = 0xff; 368*52130Smckusick MachEmptyWriteBuffer(); 369*52130Smckusick 370*52130Smckusick if (isMono) { 371*52130Smckusick vdac->mapWA = 0; MachEmptyWriteBuffer(); 372*52130Smckusick for (i = 0; i < 256; i++) { 373*52130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 374*52130Smckusick MachEmptyWriteBuffer(); 375*52130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 376*52130Smckusick MachEmptyWriteBuffer(); 377*52130Smckusick vdac->map = (i < 128) ? 0x00 : 0xff; 378*52130Smckusick MachEmptyWriteBuffer(); 379*52130Smckusick } 380*52130Smckusick } else { 381*52130Smckusick vdac->mapWA = 0; MachEmptyWriteBuffer(); 382*52130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 383*52130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 384*52130Smckusick vdac->map = 0; MachEmptyWriteBuffer(); 385*52130Smckusick 386*52130Smckusick for (i = 1; i < 256; i++) { 387*52130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 388*52130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 389*52130Smckusick vdac->map = 0xff; MachEmptyWriteBuffer(); 390*52130Smckusick } 391*52130Smckusick } 392*52130Smckusick 393*52130Smckusick for (i = 0; i < 3; i++) { 394*52130Smckusick bg_RGB[i] = 0x00; 395*52130Smckusick fg_RGB[i] = 0xff; 396*52130Smckusick } 397*52130Smckusick RestoreCursorColor(); 398*52130Smckusick } 399*52130Smckusick 400*52130Smckusick /* 401*52130Smckusick * ---------------------------------------------------------------------------- 402*52130Smckusick * 403*52130Smckusick * VDACInit -- 404*52130Smckusick * 405*52130Smckusick * Initialize the VDAC. 406*52130Smckusick * 407*52130Smckusick * Results: 408*52130Smckusick * None. 409*52130Smckusick * 410*52130Smckusick * Side effects: 411*52130Smckusick * None. 412*52130Smckusick * 413*52130Smckusick * ---------------------------------------------------------------------------- 414*52130Smckusick */ 415*52130Smckusick static void 416*52130Smckusick VDACInit() 417*52130Smckusick { 418*52130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 419*52130Smckusick 420*52130Smckusick /* 421*52130Smckusick * 422*52130Smckusick * Initialize the VDAC 423*52130Smckusick */ 424*52130Smckusick vdac->overWA = 0x04; MachEmptyWriteBuffer(); 425*52130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 426*52130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 427*52130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 428*52130Smckusick vdac->overWA = 0x08; MachEmptyWriteBuffer(); 429*52130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 430*52130Smckusick vdac->over = 0x00; MachEmptyWriteBuffer(); 431*52130Smckusick vdac->over = 0x7f; MachEmptyWriteBuffer(); 432*52130Smckusick vdac->overWA = 0x0c; MachEmptyWriteBuffer(); 433*52130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 434*52130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 435*52130Smckusick vdac->over = 0xff; MachEmptyWriteBuffer(); 436*52130Smckusick } 437*52130Smckusick 438*52130Smckusick /* 439*52130Smckusick * ---------------------------------------------------------------------------- 440*52130Smckusick * 441*52130Smckusick * LoadColorMap -- 442*52130Smckusick * 443*52130Smckusick * Load the color map. 444*52130Smckusick * 445*52130Smckusick * Results: 446*52130Smckusick * None. 447*52130Smckusick * 448*52130Smckusick * Side effects: 449*52130Smckusick * The color map is loaded. 450*52130Smckusick * 451*52130Smckusick * ---------------------------------------------------------------------------- 452*52130Smckusick */ 453*52130Smckusick static void 454*52130Smckusick LoadColorMap(ptr) 455*52130Smckusick ColorMap *ptr; 456*52130Smckusick { 457*52130Smckusick register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; 458*52130Smckusick 459*52130Smckusick if (ptr->index > 256) 460*52130Smckusick return; 461*52130Smckusick 462*52130Smckusick vdac->mapWA = ptr->index; MachEmptyWriteBuffer(); 463*52130Smckusick vdac->map = ptr->Entry.red; MachEmptyWriteBuffer(); 464*52130Smckusick vdac->map = ptr->Entry.green; MachEmptyWriteBuffer(); 465*52130Smckusick vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer(); 466*52130Smckusick } 467*52130Smckusick 468*52130Smckusick /* 469*52130Smckusick *---------------------------------------------------------------------- 470*52130Smckusick * 471*52130Smckusick * pmKbdEvent -- 472*52130Smckusick * 473*52130Smckusick * Process a received character. 474*52130Smckusick * 475*52130Smckusick * Results: 476*52130Smckusick * None. 477*52130Smckusick * 478*52130Smckusick * Side effects: 479*52130Smckusick * Events added to the queue. 480*52130Smckusick * 481*52130Smckusick *---------------------------------------------------------------------- 482*52130Smckusick */ 483*52130Smckusick void 484*52130Smckusick pmKbdEvent(ch) 485*52130Smckusick int ch; 486*52130Smckusick { 487*52130Smckusick register pmEvent *eventPtr; 488*52130Smckusick int i; 489*52130Smckusick 490*52130Smckusick if (!GraphicsOpen) 491*52130Smckusick return; 492*52130Smckusick 493*52130Smckusick /* 494*52130Smckusick * See if there is room in the queue. 495*52130Smckusick */ 496*52130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 497*52130Smckusick if (i == pmu.scrInfo.qe.eHead) 498*52130Smckusick return; 499*52130Smckusick 500*52130Smckusick /* 501*52130Smckusick * Add the event to the queue. 502*52130Smckusick */ 503*52130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 504*52130Smckusick eventPtr->type = BUTTON_RAW_TYPE; 505*52130Smckusick eventPtr->device = KEYBOARD_DEVICE; 506*52130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 507*52130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 508*52130Smckusick eventPtr->time = TO_MS(time); 509*52130Smckusick eventPtr->key = ch; 510*52130Smckusick pmu.scrInfo.qe.eTail = i; 511*52130Smckusick pmwakeup(); 512*52130Smckusick } 513*52130Smckusick 514*52130Smckusick /* 515*52130Smckusick *---------------------------------------------------------------------- 516*52130Smckusick * 517*52130Smckusick * pmMouseEvent -- 518*52130Smckusick * 519*52130Smckusick * Process a mouse event. 520*52130Smckusick * 521*52130Smckusick * Results: 522*52130Smckusick * None. 523*52130Smckusick * 524*52130Smckusick * Side effects: 525*52130Smckusick * An event is added to the event queue. 526*52130Smckusick * 527*52130Smckusick *---------------------------------------------------------------------- 528*52130Smckusick */ 529*52130Smckusick void 530*52130Smckusick pmMouseEvent(newRepPtr) 531*52130Smckusick register MouseReport *newRepPtr; 532*52130Smckusick { 533*52130Smckusick unsigned milliSec; 534*52130Smckusick int i; 535*52130Smckusick pmEvent *eventPtr; 536*52130Smckusick 537*52130Smckusick if (!GraphicsOpen) 538*52130Smckusick return; 539*52130Smckusick 540*52130Smckusick milliSec = TO_MS(time); 541*52130Smckusick 542*52130Smckusick /* 543*52130Smckusick * Check to see if we have to accelerate the mouse 544*52130Smckusick */ 545*52130Smckusick if (pmu.scrInfo.mscale >= 0) { 546*52130Smckusick if (newRepPtr->dx >= pmu.scrInfo.mthreshold) { 547*52130Smckusick newRepPtr->dx += 548*52130Smckusick (newRepPtr->dx - pmu.scrInfo.mthreshold) * 549*52130Smckusick pmu.scrInfo.mscale; 550*52130Smckusick } 551*52130Smckusick if (newRepPtr->dy >= pmu.scrInfo.mthreshold) { 552*52130Smckusick newRepPtr->dy += 553*52130Smckusick (newRepPtr->dy - pmu.scrInfo.mthreshold) * 554*52130Smckusick pmu.scrInfo.mscale; 555*52130Smckusick } 556*52130Smckusick } 557*52130Smckusick 558*52130Smckusick /* 559*52130Smckusick * Update mouse position 560*52130Smckusick */ 561*52130Smckusick if (newRepPtr->state & MOUSE_X_SIGN) { 562*52130Smckusick pmu.scrInfo.mouse.x += newRepPtr->dx; 563*52130Smckusick if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x) 564*52130Smckusick pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x; 565*52130Smckusick } else { 566*52130Smckusick pmu.scrInfo.mouse.x -= newRepPtr->dx; 567*52130Smckusick if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x) 568*52130Smckusick pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x; 569*52130Smckusick } 570*52130Smckusick if (newRepPtr->state & MOUSE_Y_SIGN) { 571*52130Smckusick pmu.scrInfo.mouse.y -= newRepPtr->dy; 572*52130Smckusick if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y) 573*52130Smckusick pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y; 574*52130Smckusick } else { 575*52130Smckusick pmu.scrInfo.mouse.y += newRepPtr->dy; 576*52130Smckusick if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y) 577*52130Smckusick pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y; 578*52130Smckusick } 579*52130Smckusick 580*52130Smckusick /* 581*52130Smckusick * Move the hardware cursor. 582*52130Smckusick */ 583*52130Smckusick PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 584*52130Smckusick 585*52130Smckusick /* 586*52130Smckusick * Store the motion event in the motion buffer. 587*52130Smckusick */ 588*52130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec; 589*52130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x; 590*52130Smckusick pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y; 591*52130Smckusick if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE) 592*52130Smckusick pmu.scrInfo.qe.tcNext = 0; 593*52130Smckusick if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom && 594*52130Smckusick pmu.scrInfo.mouse.y >= pmu.scrInfo.mbox.top && 595*52130Smckusick pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right && 596*52130Smckusick pmu.scrInfo.mouse.x >= pmu.scrInfo.mbox.left) 597*52130Smckusick return; 598*52130Smckusick 599*52130Smckusick pmu.scrInfo.mbox.bottom = 0; 600*52130Smckusick if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead) 601*52130Smckusick return; 602*52130Smckusick 603*52130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1); 604*52130Smckusick if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && 605*52130Smckusick (i != pmu.scrInfo.qe.eHead)) { 606*52130Smckusick pmEvent *eventPtr; 607*52130Smckusick 608*52130Smckusick eventPtr = &pmu.events[i]; 609*52130Smckusick if (eventPtr->type == MOTION_TYPE) { 610*52130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 611*52130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 612*52130Smckusick eventPtr->time = milliSec; 613*52130Smckusick eventPtr->device = MOUSE_DEVICE; 614*52130Smckusick return; 615*52130Smckusick } 616*52130Smckusick } 617*52130Smckusick /* 618*52130Smckusick * Put event into queue and wakeup any waiters. 619*52130Smckusick */ 620*52130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 621*52130Smckusick eventPtr->type = MOTION_TYPE; 622*52130Smckusick eventPtr->time = milliSec; 623*52130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 624*52130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 625*52130Smckusick eventPtr->device = MOUSE_DEVICE; 626*52130Smckusick pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); 627*52130Smckusick pmwakeup(); 628*52130Smckusick } 629*52130Smckusick 630*52130Smckusick /* 631*52130Smckusick *---------------------------------------------------------------------- 632*52130Smckusick * 633*52130Smckusick * pmMouseButtons -- 634*52130Smckusick * 635*52130Smckusick * Process mouse buttons. 636*52130Smckusick * 637*52130Smckusick * Results: 638*52130Smckusick * None. 639*52130Smckusick * 640*52130Smckusick * Side effects: 641*52130Smckusick * None. 642*52130Smckusick * 643*52130Smckusick *---------------------------------------------------------------------- 644*52130Smckusick */ 645*52130Smckusick void 646*52130Smckusick pmMouseButtons(newRepPtr) 647*52130Smckusick MouseReport *newRepPtr; 648*52130Smckusick { 649*52130Smckusick static char temp, oldSwitch, newSwitch; 650*52130Smckusick int i, j; 651*52130Smckusick pmEvent *eventPtr; 652*52130Smckusick static MouseReport lastRep; 653*52130Smckusick 654*52130Smckusick if (!GraphicsOpen) 655*52130Smckusick return; 656*52130Smckusick 657*52130Smckusick newSwitch = newRepPtr->state & 0x07; 658*52130Smckusick oldSwitch = lastRep.state & 0x07; 659*52130Smckusick 660*52130Smckusick temp = oldSwitch ^ newSwitch; 661*52130Smckusick if (temp == 0) 662*52130Smckusick return; 663*52130Smckusick for (j = 1; j < 8; j <<= 1) { 664*52130Smckusick if ((j & temp) == 0) 665*52130Smckusick continue; 666*52130Smckusick 667*52130Smckusick /* 668*52130Smckusick * Check for room in the queue 669*52130Smckusick */ 670*52130Smckusick i = PM_EVROUND(pmu.scrInfo.qe.eTail+1); 671*52130Smckusick if (i == pmu.scrInfo.qe.eHead) 672*52130Smckusick return; 673*52130Smckusick 674*52130Smckusick /* 675*52130Smckusick * Put event into queue. 676*52130Smckusick */ 677*52130Smckusick eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; 678*52130Smckusick 679*52130Smckusick switch (j) { 680*52130Smckusick case RIGHT_BUTTON: 681*52130Smckusick eventPtr->key = EVENT_RIGHT_BUTTON; 682*52130Smckusick break; 683*52130Smckusick 684*52130Smckusick case MIDDLE_BUTTON: 685*52130Smckusick eventPtr->key = EVENT_MIDDLE_BUTTON; 686*52130Smckusick break; 687*52130Smckusick 688*52130Smckusick case LEFT_BUTTON: 689*52130Smckusick eventPtr->key = EVENT_LEFT_BUTTON; 690*52130Smckusick } 691*52130Smckusick if (newSwitch & j) 692*52130Smckusick eventPtr->type = BUTTON_DOWN_TYPE; 693*52130Smckusick else 694*52130Smckusick eventPtr->type = BUTTON_UP_TYPE; 695*52130Smckusick eventPtr->device = MOUSE_DEVICE; 696*52130Smckusick 697*52130Smckusick eventPtr->time = TO_MS(time); 698*52130Smckusick eventPtr->x = pmu.scrInfo.mouse.x; 699*52130Smckusick eventPtr->y = pmu.scrInfo.mouse.y; 700*52130Smckusick } 701*52130Smckusick pmu.scrInfo.qe.eTail = i; 702*52130Smckusick pmwakeup(); 703*52130Smckusick 704*52130Smckusick lastRep = *newRepPtr; 705*52130Smckusick pmu.scrInfo.mswitches = newSwitch; 706*52130Smckusick } 707*52130Smckusick 708*52130Smckusick /* 709*52130Smckusick *---------------------------------------------------------------------- 710*52130Smckusick * 711*52130Smckusick * PosCursor -- 712*52130Smckusick * 713*52130Smckusick * Postion the cursor. 714*52130Smckusick * 715*52130Smckusick * Results: 716*52130Smckusick * None. 717*52130Smckusick * 718*52130Smckusick * Side effects: 719*52130Smckusick * None. 720*52130Smckusick * 721*52130Smckusick *---------------------------------------------------------------------- 722*52130Smckusick */ 723*52130Smckusick static void 724*52130Smckusick PosCursor(x, y) 725*52130Smckusick register int x, y; 726*52130Smckusick { 727*52130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 728*52130Smckusick 729*52130Smckusick if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y) 730*52130Smckusick y = pmu.scrInfo.max_cur_y; 731*52130Smckusick if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x) 732*52130Smckusick x = pmu.scrInfo.max_cur_x; 733*52130Smckusick pmu.scrInfo.cursor.x = x; /* keep track of real cursor */ 734*52130Smckusick pmu.scrInfo.cursor.y = y; /* position, indep. of mouse */ 735*52130Smckusick pcc->xpos = PCC_X_OFFSET + x; 736*52130Smckusick pcc->ypos = PCC_Y_OFFSET + y; 737*52130Smckusick } 738*52130Smckusick 739*52130Smckusick /* 740*52130Smckusick *---------------------------------------------------------------------- 741*52130Smckusick * 742*52130Smckusick * Scroll -- 743*52130Smckusick * 744*52130Smckusick * Scroll the screen. 745*52130Smckusick * 746*52130Smckusick * Results: 747*52130Smckusick * None. 748*52130Smckusick * 749*52130Smckusick * Side effects: 750*52130Smckusick * None. 751*52130Smckusick * 752*52130Smckusick *---------------------------------------------------------------------- 753*52130Smckusick */ 754*52130Smckusick static void 755*52130Smckusick Scroll() 756*52130Smckusick { 757*52130Smckusick register int *dest, *src; 758*52130Smckusick register int *end; 759*52130Smckusick register int temp0, temp1, temp2, temp3; 760*52130Smckusick register int i, scanInc, lineCount; 761*52130Smckusick int line; 762*52130Smckusick 763*52130Smckusick /* 764*52130Smckusick * If the mouse is on we don't scroll so that the bit map remains sane. 765*52130Smckusick */ 766*52130Smckusick if (GraphicsOpen) { 767*52130Smckusick pmu.scrInfo.row = 0; 768*52130Smckusick return; 769*52130Smckusick } 770*52130Smckusick 771*52130Smckusick /* 772*52130Smckusick * The following is an optimization to cause the scrolling 773*52130Smckusick * of text to be memory limited. Basically the writebuffer is 774*52130Smckusick * 4 words (32 bits ea.) long so to achieve maximum speed we 775*52130Smckusick * read and write in multiples of 4 words. We also limit the 776*52130Smckusick * size to be 80 characters for more speed. 777*52130Smckusick */ 778*52130Smckusick if (isMono) { 779*52130Smckusick lineCount = 5; 780*52130Smckusick line = 1920 * 2; 781*52130Smckusick scanInc = 44; 782*52130Smckusick } else { 783*52130Smckusick lineCount = 40; 784*52130Smckusick scanInc = 96; 785*52130Smckusick line = 1920 * 8; 786*52130Smckusick } 787*52130Smckusick src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line); 788*52130Smckusick dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR); 789*52130Smckusick end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line); 790*52130Smckusick do { 791*52130Smckusick i = 0; 792*52130Smckusick do { 793*52130Smckusick temp0 = src[0]; 794*52130Smckusick temp1 = src[1]; 795*52130Smckusick temp2 = src[2]; 796*52130Smckusick temp3 = src[3]; 797*52130Smckusick dest[0] = temp0; 798*52130Smckusick dest[1] = temp1; 799*52130Smckusick dest[2] = temp2; 800*52130Smckusick dest[3] = temp3; 801*52130Smckusick dest += 4; 802*52130Smckusick src += 4; 803*52130Smckusick i++; 804*52130Smckusick } while (i < lineCount); 805*52130Smckusick src += scanInc; 806*52130Smckusick dest += scanInc; 807*52130Smckusick } while (src < end); 808*52130Smckusick 809*52130Smckusick /* 810*52130Smckusick * Now zero out the last two lines 811*52130Smckusick */ 812*52130Smckusick bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (pmu.scrInfo.row * line), 813*52130Smckusick 3 * line); 814*52130Smckusick } 815*52130Smckusick 816*52130Smckusick /* 817*52130Smckusick *---------------------------------------------------------------------- 818*52130Smckusick * 819*52130Smckusick * pmPutc -- 820*52130Smckusick * 821*52130Smckusick * Write a character to the console. 822*52130Smckusick * 823*52130Smckusick * Results: 824*52130Smckusick * None. 825*52130Smckusick * 826*52130Smckusick * Side effects: 827*52130Smckusick * None. 828*52130Smckusick * 829*52130Smckusick *---------------------------------------------------------------------- 830*52130Smckusick */ 831*52130Smckusick pmPutc(c) 832*52130Smckusick register int c; 833*52130Smckusick { 834*52130Smckusick int s; 835*52130Smckusick 836*52130Smckusick s = splhigh(); /* in case we do any printf's at interrupt time */ 837*52130Smckusick if (initialized) { 838*52130Smckusick #ifdef DEBUG 839*52130Smckusick /* 840*52130Smckusick * If the HELP key is pressed, wait for another 841*52130Smckusick * HELP key press to start/stop output. 842*52130Smckusick */ 843*52130Smckusick if (dcKBDGetc() == LK_HELP) { 844*52130Smckusick while (dcKBDGetc() != LK_HELP) 845*52130Smckusick ; 846*52130Smckusick } 847*52130Smckusick #endif 848*52130Smckusick Blitc(c); 849*52130Smckusick } else { 850*52130Smckusick void (*f)() = (void (*)())MACH_MON_PUTCHAR; 851*52130Smckusick 852*52130Smckusick (*f)(c); 853*52130Smckusick } 854*52130Smckusick splx(s); 855*52130Smckusick } 856*52130Smckusick 857*52130Smckusick /* 858*52130Smckusick *---------------------------------------------------------------------- 859*52130Smckusick * 860*52130Smckusick * Blitc -- 861*52130Smckusick * 862*52130Smckusick * Write a character to the screen. 863*52130Smckusick * 864*52130Smckusick * Results: 865*52130Smckusick * None. 866*52130Smckusick * 867*52130Smckusick * Side effects: 868*52130Smckusick * None. 869*52130Smckusick * 870*52130Smckusick *---------------------------------------------------------------------- 871*52130Smckusick */ 872*52130Smckusick static void 873*52130Smckusick Blitc(c) 874*52130Smckusick register int c; 875*52130Smckusick { 876*52130Smckusick register char *bRow, *fRow; 877*52130Smckusick register int i; 878*52130Smckusick register int ote = isMono ? 256 : 1024; /* offset to table entry */ 879*52130Smckusick int colMult = isMono ? 1 : 8; 880*52130Smckusick 881*52130Smckusick c &= 0xff; 882*52130Smckusick 883*52130Smckusick switch (c) { 884*52130Smckusick case '\t': 885*52130Smckusick for (i = 8 - (pmu.scrInfo.col & 0x7); i > 0; i--) 886*52130Smckusick Blitc(' '); 887*52130Smckusick break; 888*52130Smckusick 889*52130Smckusick case '\r': 890*52130Smckusick pmu.scrInfo.col = 0; 891*52130Smckusick break; 892*52130Smckusick 893*52130Smckusick case '\b': 894*52130Smckusick pmu.scrInfo.col--; 895*52130Smckusick if (pmu.scrInfo.col < 0) 896*52130Smckusick pmu.scrInfo.col = 0; 897*52130Smckusick break; 898*52130Smckusick 899*52130Smckusick case '\n': 900*52130Smckusick if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row) 901*52130Smckusick Scroll(); 902*52130Smckusick else 903*52130Smckusick pmu.scrInfo.row++; 904*52130Smckusick pmu.scrInfo.col = 0; 905*52130Smckusick break; 906*52130Smckusick 907*52130Smckusick case '\007': 908*52130Smckusick dcKBDPutc(LK_RING_BELL); 909*52130Smckusick break; 910*52130Smckusick 911*52130Smckusick default: 912*52130Smckusick /* 913*52130Smckusick * If the next character will wrap around then 914*52130Smckusick * increment row counter or scroll screen. 915*52130Smckusick */ 916*52130Smckusick if (pmu.scrInfo.col >= pmu.scrInfo.max_col) { 917*52130Smckusick pmu.scrInfo.col = 0; 918*52130Smckusick if (pmu.scrInfo.row + 1 >= pmu.scrInfo.max_row) 919*52130Smckusick Scroll(); 920*52130Smckusick else 921*52130Smckusick pmu.scrInfo.row++; 922*52130Smckusick } 923*52130Smckusick /* 924*52130Smckusick * 0xA1 to 0xFD are the printable characters added with 8-bit 925*52130Smckusick * support. 926*52130Smckusick */ 927*52130Smckusick if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD) 928*52130Smckusick break; 929*52130Smckusick bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + 930*52130Smckusick (pmu.scrInfo.row * 15 & 0x3ff) * ote + 931*52130Smckusick pmu.scrInfo.col * colMult); 932*52130Smckusick i = c - ' '; 933*52130Smckusick /* 934*52130Smckusick * This is to skip the (32) 8-bit 935*52130Smckusick * control chars, as well as DEL 936*52130Smckusick * and 0xA0 which aren't printable 937*52130Smckusick */ 938*52130Smckusick if (c > '~') 939*52130Smckusick i -= 34; 940*52130Smckusick i *= 15; 941*52130Smckusick fRow = (char *)((int)pmFont + i); 942*52130Smckusick 943*52130Smckusick /* inline expansion for speed */ 944*52130Smckusick if (isMono) { 945*52130Smckusick *bRow = *fRow++; bRow += ote; 946*52130Smckusick *bRow = *fRow++; bRow += ote; 947*52130Smckusick *bRow = *fRow++; bRow += ote; 948*52130Smckusick *bRow = *fRow++; bRow += ote; 949*52130Smckusick *bRow = *fRow++; bRow += ote; 950*52130Smckusick *bRow = *fRow++; bRow += ote; 951*52130Smckusick *bRow = *fRow++; bRow += ote; 952*52130Smckusick *bRow = *fRow++; bRow += ote; 953*52130Smckusick *bRow = *fRow++; bRow += ote; 954*52130Smckusick *bRow = *fRow++; bRow += ote; 955*52130Smckusick *bRow = *fRow++; bRow += ote; 956*52130Smckusick *bRow = *fRow++; bRow += ote; 957*52130Smckusick *bRow = *fRow++; bRow += ote; 958*52130Smckusick *bRow = *fRow++; bRow += ote; 959*52130Smckusick *bRow = *fRow++; bRow += ote; 960*52130Smckusick } else { 961*52130Smckusick register int j; 962*52130Smckusick register unsigned int *pInt; 963*52130Smckusick 964*52130Smckusick pInt = (unsigned int *)bRow; 965*52130Smckusick for (j = 0; j < 15; j++) { 966*52130Smckusick /* 967*52130Smckusick * fontmaskBits converts a nibble 968*52130Smckusick * (4 bytes) to a long word 969*52130Smckusick * containing 4 pixels corresponding 970*52130Smckusick * to each bit in the nibble. Thus 971*52130Smckusick * we write two longwords for each 972*52130Smckusick * byte in font. 973*52130Smckusick * 974*52130Smckusick * Remember the font is 8 bits wide 975*52130Smckusick * and 15 bits high. 976*52130Smckusick * 977*52130Smckusick * We add 256 to the pointer to 978*52130Smckusick * point to the pixel on the 979*52130Smckusick * next scan line 980*52130Smckusick * directly below the current 981*52130Smckusick * pixel. 982*52130Smckusick */ 983*52130Smckusick pInt[0] = fontmaskBits[(*fRow) & 0xf]; 984*52130Smckusick pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf]; 985*52130Smckusick fRow++; 986*52130Smckusick pInt += 256; 987*52130Smckusick } 988*52130Smckusick } 989*52130Smckusick pmu.scrInfo.col++; /* increment column counter */ 990*52130Smckusick } 991*52130Smckusick if (!GraphicsOpen) 992*52130Smckusick PosCursor(pmu.scrInfo.col * 8, pmu.scrInfo.row * 15); 993*52130Smckusick } 994*52130Smckusick 995*52130Smckusick /*ARGSUSED*/ 996*52130Smckusick pmopen(dev, flag) 997*52130Smckusick dev_t dev; 998*52130Smckusick int flag; 999*52130Smckusick { 1000*52130Smckusick 1001*52130Smckusick if (!initialized) 1002*52130Smckusick return (ENXIO); 1003*52130Smckusick if (GraphicsOpen) 1004*52130Smckusick return (EBUSY); 1005*52130Smckusick 1006*52130Smckusick GraphicsOpen = 1; 1007*52130Smckusick if (!isMono) 1008*52130Smckusick InitColorMap(); 1009*52130Smckusick /* 1010*52130Smckusick * Set up event queue for later 1011*52130Smckusick */ 1012*52130Smckusick pmu.scrInfo.qe.eSize = PM_MAXEVQ; 1013*52130Smckusick pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; 1014*52130Smckusick pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; 1015*52130Smckusick pmu.scrInfo.qe.tcNext = 0; 1016*52130Smckusick pmu.scrInfo.qe.timestamp_ms = TO_MS(time); 1017*52130Smckusick return (0); 1018*52130Smckusick } 1019*52130Smckusick 1020*52130Smckusick /*ARGSUSED*/ 1021*52130Smckusick pmclose(dev, flag) 1022*52130Smckusick dev_t dev; 1023*52130Smckusick int flag; 1024*52130Smckusick { 1025*52130Smckusick 1026*52130Smckusick if (!GraphicsOpen) 1027*52130Smckusick return (EBADF); 1028*52130Smckusick 1029*52130Smckusick GraphicsOpen = 0; 1030*52130Smckusick if (!isMono) 1031*52130Smckusick InitColorMap(); 1032*52130Smckusick ScreenInit(); 1033*52130Smckusick vmUserUnmap(); 1034*52130Smckusick return (0); 1035*52130Smckusick } 1036*52130Smckusick 1037*52130Smckusick /*ARGSUSED*/ 1038*52130Smckusick pmioctl(dev, cmd, data, flag) 1039*52130Smckusick dev_t dev; 1040*52130Smckusick caddr_t data; 1041*52130Smckusick { 1042*52130Smckusick register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; 1043*52130Smckusick extern int dcDivertXInput; 1044*52130Smckusick 1045*52130Smckusick switch (cmd) { 1046*52130Smckusick case QIOCGINFO: 1047*52130Smckusick { 1048*52130Smckusick caddr_t addr; 1049*52130Smckusick extern caddr_t vmUserMap(); 1050*52130Smckusick 1051*52130Smckusick /* 1052*52130Smckusick * Map the all the data the user needs access to into 1053*52130Smckusick * user space. 1054*52130Smckusick */ 1055*52130Smckusick addr = vmUserMap(sizeof(pmu), (unsigned)&pmu); 1056*52130Smckusick if (addr == (caddr_t)0) 1057*52130Smckusick goto mapError; 1058*52130Smckusick *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo; 1059*52130Smckusick pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events; 1060*52130Smckusick pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs; 1061*52130Smckusick /* 1062*52130Smckusick * Map the plane mask into the user's address space. 1063*52130Smckusick */ 1064*52130Smckusick addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR); 1065*52130Smckusick if (addr == (caddr_t)0) 1066*52130Smckusick goto mapError; 1067*52130Smckusick pmu.scrInfo.planemask = (char *)addr; 1068*52130Smckusick /* 1069*52130Smckusick * Map the bitmap into the user's address space. 1070*52130Smckusick */ 1071*52130Smckusick addr = vmUserMap(isMono ? 256*1024 : 1024*1024, 1072*52130Smckusick (unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR); 1073*52130Smckusick if (addr == (caddr_t)0) 1074*52130Smckusick goto mapError; 1075*52130Smckusick pmu.scrInfo.bitmap = (char *)addr; 1076*52130Smckusick break; 1077*52130Smckusick 1078*52130Smckusick mapError: 1079*52130Smckusick vmUserUnmap(); 1080*52130Smckusick printf("Cannot map shared data structures\n"); 1081*52130Smckusick return (EIO); 1082*52130Smckusick } 1083*52130Smckusick 1084*52130Smckusick case QIOCPMSTATE: 1085*52130Smckusick /* 1086*52130Smckusick * Set mouse state. 1087*52130Smckusick */ 1088*52130Smckusick pmu.scrInfo.mouse = *(pmCursor *)data; 1089*52130Smckusick PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); 1090*52130Smckusick break; 1091*52130Smckusick 1092*52130Smckusick case QIOCINIT: 1093*52130Smckusick /* 1094*52130Smckusick * Initialize the screen. 1095*52130Smckusick */ 1096*52130Smckusick ScreenInit(); 1097*52130Smckusick break; 1098*52130Smckusick 1099*52130Smckusick case QIOCKPCMD: 1100*52130Smckusick { 1101*52130Smckusick pmKpCmd *kpCmdPtr; 1102*52130Smckusick unsigned char *cp; 1103*52130Smckusick 1104*52130Smckusick kpCmdPtr = (pmKpCmd *)data; 1105*52130Smckusick if (kpCmdPtr->nbytes == 0) 1106*52130Smckusick kpCmdPtr->cmd |= 0x80; 1107*52130Smckusick if (!GraphicsOpen) 1108*52130Smckusick kpCmdPtr->cmd |= 1; 1109*52130Smckusick dcKBDPutc((int)kpCmdPtr->cmd); 1110*52130Smckusick cp = &kpCmdPtr->par[0]; 1111*52130Smckusick for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { 1112*52130Smckusick if (kpCmdPtr->nbytes == 1) 1113*52130Smckusick *cp |= 0x80; 1114*52130Smckusick dcKBDPutc((int)*cp); 1115*52130Smckusick } 1116*52130Smckusick break; 1117*52130Smckusick } 1118*52130Smckusick 1119*52130Smckusick case QIOCADDR: 1120*52130Smckusick *(PM_Info **)data = &pmu.scrInfo; 1121*52130Smckusick break; 1122*52130Smckusick 1123*52130Smckusick case QIOWCURSOR: 1124*52130Smckusick LoadCursor((unsigned short *)data); 1125*52130Smckusick break; 1126*52130Smckusick 1127*52130Smckusick case QIOWCURSORCOLOR: 1128*52130Smckusick CursorColor((unsigned int *)data); 1129*52130Smckusick break; 1130*52130Smckusick 1131*52130Smckusick case QIOSETCMAP: 1132*52130Smckusick LoadColorMap((ColorMap *)data); 1133*52130Smckusick break; 1134*52130Smckusick 1135*52130Smckusick case QIOKERNLOOP: 1136*52130Smckusick printf("pmioctl: QIOKERNLOOP\n"); /* XXX */ 1137*52130Smckusick dcDivertXInput = 1; 1138*52130Smckusick break; 1139*52130Smckusick 1140*52130Smckusick case QIOKERNUNLOOP: 1141*52130Smckusick printf("pmioctl: QIOKERNUNLOOP\n"); /* XXX */ 1142*52130Smckusick dcDivertXInput = 0; 1143*52130Smckusick break; 1144*52130Smckusick 1145*52130Smckusick case QIOVIDEOON: 1146*52130Smckusick if (!isMono) 1147*52130Smckusick RestoreCursorColor(); 1148*52130Smckusick curReg |= PCC_ENPA; 1149*52130Smckusick curReg &= ~PCC_FOPB; 1150*52130Smckusick pcc->cmdr = curReg; 1151*52130Smckusick break; 1152*52130Smckusick 1153*52130Smckusick case QIOVIDEOOFF: 1154*52130Smckusick if (!isMono) 1155*52130Smckusick VDACInit(); 1156*52130Smckusick curReg |= PCC_FOPB; 1157*52130Smckusick curReg &= ~PCC_ENPA; 1158*52130Smckusick pcc->cmdr = curReg; 1159*52130Smckusick break; 1160*52130Smckusick 1161*52130Smckusick default: 1162*52130Smckusick printf("pm0: Unknown command %x\n", cmd); 1163*52130Smckusick return (EINVAL); 1164*52130Smckusick } 1165*52130Smckusick return (0); 1166*52130Smckusick } 1167*52130Smckusick 1168*52130Smckusick pmselect(dev, flag) 1169*52130Smckusick dev_t dev; 1170*52130Smckusick int flag; 1171*52130Smckusick { 1172*52130Smckusick 1173*52130Smckusick switch (flag) { 1174*52130Smckusick case FREAD: 1175*52130Smckusick if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail) 1176*52130Smckusick return (1); 1177*52130Smckusick pm_selp = curproc; 1178*52130Smckusick break; 1179*52130Smckusick } 1180*52130Smckusick 1181*52130Smckusick return (0); 1182*52130Smckusick } 1183*52130Smckusick 1184*52130Smckusick static 1185*52130Smckusick pmwakeup() 1186*52130Smckusick { 1187*52130Smckusick 1188*52130Smckusick if (pm_selp) { 1189*52130Smckusick selwakeup(pm_selp, 0); 1190*52130Smckusick pm_selp = 0; 1191*52130Smckusick } 1192*52130Smckusick } 1193*52130Smckusick #endif 1194