1*30391Skarels 2*30391Skarels #ifndef lint 3*30391Skarels static char *sccsid = "@(#)qd.c 1.40 ULTRIX 10/2/86"; 4*30391Skarels #endif lint 5*30391Skarels 6*30391Skarels /************************************************************************ 7*30391Skarels * * 8*30391Skarels * Copyright (c) 1985, 1986 by * 9*30391Skarels * Digital Equipment Corporation, Maynard, MA * 10*30391Skarels * All rights reserved. * 11*30391Skarels * * 12*30391Skarels * This software is furnished under a license and may be used and * 13*30391Skarels * copied only in accordance with the terms of such license and * 14*30391Skarels * with the inclusion of the above copyright notice. This * 15*30391Skarels * software or any other copies thereof may not be provided or * 16*30391Skarels * otherwise made available to any other person. No title to and * 17*30391Skarels * ownership of the software is hereby transferred. * 18*30391Skarels * * 19*30391Skarels * The information in this software is subject to change without * 20*30391Skarels * notice and should not be construed as a commitment by Digital * 21*30391Skarels * Equipment Corporation. * 22*30391Skarels * * 23*30391Skarels * Digital assumes no responsibility for the use or reliability * 24*30391Skarels * of its software on equipment which is not supplied by Digital. * 25*30391Skarels * * 26*30391Skarels *************************************************************************/ 27*30391Skarels 28*30391Skarels /* 29*30391Skarels * qd.c 30*30391Skarels * 31*30391Skarels * Modification history 32*30391Skarels * 33*30391Skarels * QDSS workstation driver 34*30391Skarels * 35*30391Skarels * 26-Aug-86 - rsp (Ricky Palmer) 36*30391Skarels * 37*30391Skarels * Cleaned up devioctl code to (1) zero out devget structure 38*30391Skarels * upon entry and (2) use strlen instead of fixed storage 39*30391Skarels * for bcopy's. 40*30391Skarels * 41*30391Skarels * 21-Jul-86 - Ram Rao 42*30391Skarels * allowed cursor rectangle to hang (partially) off the 43*30391Skarels * top and left of screen 44*30391Skarels * 45*30391Skarels * 11-Jul-86 - ricky palmer 46*30391Skarels * 47*30391Skarels * Added adpt and nexus fields to DEVIOCGET code. 48*30391Skarels * 49*30391Skarels * 02-July-86 - Brian Stevens 50*30391Skarels * 51*30391Skarels * added support for console writing to second QDSS display 52*30391Skarels * 53*30391Skarels * 20-May-86 - ricky palmer 54*30391Skarels * 55*30391Skarels * Added new DEVIOCGET ioctl request code. V2.0 56*30391Skarels * 57*30391Skarels * 16-Apr-86 -- darrell 58*30391Skarels * badaddr is now called via the macro BADADDR 59*30391Skarels * 60*30391Skarels * 14-Apr-86 -- afd 61*30391Skarels * Changed UMEMmap to QMEMmap and umem to qmem. 62*30391Skarels * 63*30391Skarels * v_console() is now refered to as v_consputc, and there is a 64*30391Skarels * corresponding v_consgetc() (defined in /sys/vax/conf.c). 65*30391Skarels * 66*30391Skarels * Added "qdgetc()" routine for console read. Needed to read 67*30391Skarels * user's answer to the "root device?" prompt with a generic kernel. 68*30391Skarels * 69*30391Skarels * 19-Mar-86 -- pmk 70*30391Skarels * Change DELAY to 20000, because microdelay now in real microsec. 71*30391Skarels * 72*30391Skarels * 18-mar-86 -- jaw br/cvec changed to NOT use registers. 73*30391Skarels * 74*30391Skarels * 11 mar 86 darrell replaced percpu with cpusw, and removed all but 75*30391Skarels * one global reference 76*30391Skarels * 19 feb 86 bstevens no report of motion event on puck/stylus button action 77*30391Skarels * 18 feb 86 bstevens put in cursor box support for tablets 78*30391Skarels * 18-Mar-86 -- jaw add routines to cpu switch for nexus/unibus addreses 79*30391Skarels * also got rid of some globals like nexnum. 80*30391Skarels * ka8800 cleanup. 81*30391Skarels * 06 dec 85 longo added LK-201 error reporting for graphics device ops 82*30391Skarels * 03 dec 85 longo made qddint() clear active bit on error 83*30391Skarels * 02 dec 85 longo fixed up some crocks in the error messages 84*30391Skarels * 25 nov 85 longo added error handling to DMA ISR and single user locking 85*30391Skarels * 19 nov 85 longo eliminated "set_defaults()" by breaking out sub-calls. 86*30391Skarels * Changed init_shared to do real init of scroll struct 87*30391Skarels * 12 nov 85 longo fixed bug in open that broke alternate console re-direct 88*30391Skarels * 11 nov 85 longo changed "_vs_eventqueue" references to "qdinput" 89*30391Skarels * 08 nov 85 longo improved select service for read/write select wakeup. 90*30391Skarels * Also set ISR's to ipl4 to allow the interval timer in. 91*30391Skarels * 04 nov 85 longo fixed bugs in mouse button reporting and dma request stuff 92*30391Skarels * 30 oct 85 longo DMA to/from user space is in place 93*30391Skarels * 14 oct 85 longo added kernel msg redirect and QD_RDCURSOR ioctl 94*30391Skarels * 03 oct 85 longo added support for multiple QDSS's 95*30391Skarels * 02 oct 85 longo added color map loading services in qdioctl() & qdaint() 96*30391Skarels * 30 sep 85 longo added DMA interrupt services 97*30391Skarels * 18 sep 85 longo added scroll services to "qdaint()" adder intrpt service 98*30391Skarels * and put in supporting ioctl's 99*30391Skarels * 04 sep 85 longo initial implementation of DMA is working 100*30391Skarels * 17 aug 85 longo added support for the QDSS to be system console 101*30391Skarels * 05 aug 85 longo now using qfont (QVSS & QDSS) as linked object 102*30391Skarels * 12 jun 85 longo added mouse event loading to "qdiint()" 103*30391Skarels * 31 may 85 longo put live interrupts into the probe() routine 104*30391Skarels * 30 may 85 longo event queue shared memory implementation is now alive 105*30391Skarels * 29 may 85 longo LK-201 input is now interrupt driven 106*30391Skarels * 25 apr 85 longo MAPDEVICE works 107*30391Skarels * 14 mar 85 longo created 108*30391Skarels * 109*30391Skarels * todo: fix rlogin bug in console stuff 110*30391Skarels * cat -u console redirection 111*30391Skarels * check error return from strategy routine 112*30391Skarels * verify TOY time stuff (what format?) 113*30391Skarels * look at system based macro implementation of VTOP 114*30391Skarels * 115*30391Skarels */ 116*30391Skarels 117*30391Skarels #include "../data/qd_data.c" /* include external references to data file */ 118*30391Skarels 119*30391Skarels /*--------------------------------------------------------------------- 120*30391Skarels * macro to get system time. Used to time stamp event queue entries */ 121*30391Skarels 122*30391Skarels #define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000)) 123*30391Skarels 124*30391Skarels /*-------------------------------------------------------------------------- 125*30391Skarels * the "ioconf.c" program, built and used by auto config, externally refers 126*30391Skarels * to definitions below. */ 127*30391Skarels 128*30391Skarels int qdprobe(); 129*30391Skarels int qdattach(); 130*30391Skarels int qddint(); /* DMA gate array intrpt service */ 131*30391Skarels int qdaint(); /* Dragon ADDER intrpt service */ 132*30391Skarels int qdiint(); 133*30391Skarels 134*30391Skarels u_short qdstd[] = { 0 }; 135*30391Skarels 136*30391Skarels struct uba_driver qddriver = { /* externally referenced: ioconf.c */ 137*30391Skarels 138*30391Skarels qdprobe, /* device probe entry */ 139*30391Skarels 0, /* no slave device */ 140*30391Skarels qdattach, /* device attach entry */ 141*30391Skarels 0, /* no "fill csr/ba to start" */ 142*30391Skarels qdstd, /* device addresses */ 143*30391Skarels "qd", /* device name string */ 144*30391Skarels qdinfo /* ptr to QDSS's uba_device struct */ 145*30391Skarels }; 146*30391Skarels 147*30391Skarels /*------------------- 148*30391Skarels * general defines */ 149*30391Skarels 150*30391Skarels #define QDPRIOR (PZERO-1) /* must be negative */ 151*30391Skarels 152*30391Skarels #define FALSE 0 153*30391Skarels #define TRUE ~FALSE 154*30391Skarels 155*30391Skarels #define BAD -1 156*30391Skarels #define GOOD 0 157*30391Skarels 158*30391Skarels /*----------------------------------------------------------------------- 159*30391Skarels * macro to create a system virtual page number from system virtual adrs */ 160*30391Skarels 161*30391Skarels #define VTOP(x) (((int)x & ~0xC0000000) >> PGSHIFT) /* convert qmem adrs */ 162*30391Skarels /* to system page # */ 163*30391Skarels 164*30391Skarels /*------------------------------------------------------------------ 165*30391Skarels * QDSS register address offsets from start of QDSS address space */ 166*30391Skarels 167*30391Skarels #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ 168*30391Skarels 169*30391Skarels #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ 170*30391Skarels #define TMPSTART 0x8000 /* offset of template RAM from base adrs */ 171*30391Skarels 172*30391Skarels #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ 173*30391Skarels #define REGSTART 0xC000 /* offset of reg pages from base adrs */ 174*30391Skarels 175*30391Skarels #define ADDER (REGSTART+0x000) 176*30391Skarels #define DGA (REGSTART+0x200) 177*30391Skarels #define DUART (REGSTART+0x400) 178*30391Skarels #define MEMCSR (REGSTART+0x800) 179*30391Skarels 180*30391Skarels #define CLRSIZE (3 * 512) /* color map size */ 181*30391Skarels #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ 182*30391Skarels /* 0x0C00 really */ 183*30391Skarels #define RED (CLRSTART+0x000) 184*30391Skarels #define BLUE (CLRSTART+0x200) 185*30391Skarels #define GREEN (CLRSTART+0x400) 186*30391Skarels 187*30391Skarels /*--------------------------------------------------------------- 188*30391Skarels * values used in mapping QDSS hardware into the Q memory space */ 189*30391Skarels 190*30391Skarels #define CHUNK (64 * 1024) 191*30391Skarels #define QMEMSIZE (1024 * 1024 * 4) /* 4 meg */ 192*30391Skarels 193*30391Skarels /*---------------------------------------------------------------------- 194*30391Skarels * QDSS minor device numbers. The *real* minor device numbers are in 195*30391Skarels * the bottom two bits of the major/minor device spec. Bits 2 and up are 196*30391Skarels * used to specify the QDSS device number (ie: which one?) */ 197*30391Skarels 198*30391Skarels #define QDSSMAJOR 42 /* QDSS major device number */ 199*30391Skarels 200*30391Skarels #define CONS 0 201*30391Skarels #define ALTCONS 1 202*30391Skarels #define GRAPHIC 2 203*30391Skarels 204*30391Skarels /*---------------------------------------------- 205*30391Skarels * console cursor bitmap (block cursor type) */ 206*30391Skarels 207*30391Skarels short cons_cursor[32] = { /* white block cursor */ 208*30391Skarels 209*30391Skarels /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 210*30391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 211*30391Skarels /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 212*30391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 213*30391Skarels 214*30391Skarels }; 215*30391Skarels 216*30391Skarels /*------------------------------------- 217*30391Skarels * constants used in font operations */ 218*30391Skarels 219*30391Skarels #define CHARS 95 /* # of chars in the font */ 220*30391Skarels #define CHAR_HEIGHT 15 /* char height in pixels */ 221*30391Skarels #define CHAR_WIDTH 8 /* char width in pixels*/ 222*30391Skarels #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ 223*30391Skarels #define ROWS CHAR_HEIGHT 224*30391Skarels 225*30391Skarels 226*30391Skarels #define FONT_X 0 /* font's off screen adrs */ 227*30391Skarels #define FONT_Y (2048 - CHAR_HEIGHT) 228*30391Skarels /* 229*30391Skarels #define FONT_Y 200 230*30391Skarels */ 231*30391Skarels 232*30391Skarels extern char q_font[]; /* reference font object code */ 233*30391Skarels 234*30391Skarels extern char q_key[]; /* reference key xlation tables */ 235*30391Skarels extern char q_shift_key[]; 236*30391Skarels extern char *q_special[]; 237*30391Skarels 238*30391Skarels /*-------------------------------------------------- 239*30391Skarels * definitions for cursor acceleration reporting */ 240*30391Skarels 241*30391Skarels #define ACC_OFF 0x01 /* acceleration is inactive */ 242*30391Skarels 243*30391Skarels /*-------------------------------------------------------------------------- 244*30391Skarels * v_consputc is the switch that is used to redirect the console cnputc() to 245*30391Skarels * the virtual console qdputc(). 246*30391Skarels * v_consgetc is the switch that is used to redirect the console getchar() to 247*30391Skarels * the virtual console qdgetc(). 248*30391Skarels */ 249*30391Skarels 250*30391Skarels extern (*v_consputc)(); 251*30391Skarels int qdputc(); /* used to direct kernel console output */ 252*30391Skarels extern (*v_consgetc)(); 253*30391Skarels int qdgetc(); /* used to read kernel console input */ 254*30391Skarels 255*30391Skarels int qdstart(); /* used to direct /dev/console output */ 256*30391Skarels 257*30391Skarels /*------------------------------------------------------------------------ 258*30391Skarels * LK-201 state storage for input console keyboard conversion to ASCII */ 259*30391Skarels 260*30391Skarels struct q_keyboard { 261*30391Skarels 262*30391Skarels int shift; /* state variables */ 263*30391Skarels int cntrl; 264*30391Skarels int lock; 265*30391Skarels int lastcode; /* last keycode typed */ 266*30391Skarels unsigned kup[8]; /* bits for each keycode*/ 267*30391Skarels unsigned dkeys[8]; /* down/up mode keys */ 268*30391Skarels char last; /* last character */ 269*30391Skarels 270*30391Skarels } q_keyboard; 271*30391Skarels 272*30391Skarels 273*30391Skarels /***************************************************************** 274*30391Skarels ****************************************************************** 275*30391Skarels ****************************************************************** 276*30391Skarels * 277*30391Skarels * DRIVER FUNCTIONS START HERE: 278*30391Skarels * 279*30391Skarels ****************************************************************** 280*30391Skarels ****************************************************************** 281*30391Skarels *****************************************************************/ 282*30391Skarels 283*30391Skarels /********************************************************************* 284*30391Skarels * 285*30391Skarels * qdcons_init()... init QDSS as console (before probe routine) 286*30391Skarels * 287*30391Skarels *********************************************************************/ 288*30391Skarels 289*30391Skarels qdcons_init() 290*30391Skarels { 291*30391Skarels register u_int unit; 292*30391Skarels 293*30391Skarels int *ptep; /* page table entry pointer */ 294*30391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 295*30391Skarels u_int mapix; /* index into QMEMmap[] array */ 296*30391Skarels 297*30391Skarels struct cpusw *cpup; /* pointer to cpusw structure */ 298*30391Skarels u_short *qdaddr; /* address of QDSS IO page CSR */ 299*30391Skarels u_short *devptr; /* vitual device space */ 300*30391Skarels 301*30391Skarels #define QDSSCSR 0x1F00 302*30391Skarels 303*30391Skarels unit = 0; 304*30391Skarels 305*30391Skarels /*---------------------------------------------------- 306*30391Skarels * find the cpusw entry that matches this machine. */ 307*30391Skarels 308*30391Skarels cpup = &cpusw[cpu]; 309*30391Skarels ; 310*30391Skarels if( cpup == NULL ) { 311*30391Skarels return(0); 312*30391Skarels } 313*30391Skarels 314*30391Skarels /*------------------------------------------------------ 315*30391Skarels * Map the Q-bus memory space into the system memory. */ 316*30391Skarels 317*30391Skarels ubaaccess(((*cpup->v_umaddr)(0)), QMEMmap[0], 318*30391Skarels cpup->pc_umsize, PG_V | PG_KW); 319*30391Skarels 320*30391Skarels ubaaccess(((*cpup->v_udevaddr)(0)), QMEMmap[0]+btop(cpup->pc_umsize), 321*30391Skarels DEVSPACESIZE ,PG_V|PG_KW); 322*30391Skarels 323*30391Skarels /*--------------------------------------------------------------------- 324*30391Skarels * map the QDSS into the Qbus memory (which is now in system space) */ 325*30391Skarels 326*30391Skarels devptr = (u_short *)((char *)qmem[0]+cpup->pc_umsize); 327*30391Skarels qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 328*30391Skarels 329*30391Skarels if (BADADDR(qdaddr, sizeof(short))) 330*30391Skarels return(0); 331*30391Skarels 332*30391Skarels /*--------------------------------------------------- 333*30391Skarels * tell QDSS which Q memory address base to decode */ 334*30391Skarels 335*30391Skarels mapix = (int) VTOP(QMEMSIZE - CHUNK); 336*30391Skarels ptep = (int *) QMEMmap[0] + mapix; 337*30391Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 338*30391Skarels *qdaddr = (u_short) ((int)phys_adr >> 16); 339*30391Skarels 340*30391Skarels qdflags[unit].config = *(u_short *)qdaddr; 341*30391Skarels 342*30391Skarels /*---------------------------------------------------------------------- 343*30391Skarels * load qdmap struct with the virtual addresses of the QDSS elements */ 344*30391Skarels 345*30391Skarels qdbase[unit] = (caddr_t) (qmem[0] + QMEMSIZE - CHUNK); 346*30391Skarels 347*30391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 348*30391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 349*30391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 350*30391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 351*30391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 352*30391Skarels qdmap[unit].red = qdbase[unit] + RED; 353*30391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 354*30391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 355*30391Skarels 356*30391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 357*30391Skarels 358*30391Skarels /*------------------ 359*30391Skarels * init the QDSS */ 360*30391Skarels 361*30391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */ 362*30391Skarels 363*30391Skarels cursor[unit].x = 0; 364*30391Skarels cursor[unit].y = 0; 365*30391Skarels init_shared(unit); /* init shared memory */ 366*30391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 367*30391Skarels clear_qd_screen(unit); /* clear the screen */ 368*30391Skarels ldfont(unit); /* load the console font */ 369*30391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 370*30391Skarels setup_input(unit); /* init the DUART */ 371*30391Skarels 372*30391Skarels /*---------------------------------------------------- 373*30391Skarels * smash the system's virtual console address table */ 374*30391Skarels 375*30391Skarels v_consputc = qdputc; 376*30391Skarels v_consgetc = qdgetc; 377*30391Skarels cdevsw[0] = cdevsw[QDSSMAJOR]; 378*30391Skarels return(1); 379*30391Skarels 380*30391Skarels } /* qdcons_init */ 381*30391Skarels 382*30391Skarels /********************************************************************* 383*30391Skarels * 384*30391Skarels * qdprobe()... configure QDSS into Q memory and make it intrpt 385*30391Skarels * 386*30391Skarels ********************************************************************** 387*30391Skarels * 388*30391Skarels * calling convention: 389*30391Skarels * qdprobe(reg, ctlr); 390*30391Skarels * caddr_t reg; 391*30391Skarels * int ctlr; 392*30391Skarels * 393*30391Skarels * where: reg - a character pointer to the QDSS I/O page register 394*30391Skarels * ctlr - controller number (?) 395*30391Skarels * 396*30391Skarels * side effects: QDSS gets mapped into Qbus memory space at the first 397*30391Skarels * vacant 64kb boundary counting back from the top of 398*30391Skarels * Qbus memory space (qmem+4mb) 399*30391Skarels * 400*30391Skarels * return: QDSS bus request level and vector address returned in 401*30391Skarels * registers by UNIX convention. 402*30391Skarels * 403*30391Skarels *****************/ 404*30391Skarels 405*30391Skarels qdprobe(reg) 406*30391Skarels caddr_t reg; 407*30391Skarels { 408*30391Skarels /* the variables MUST reside in the first two register declarations 409*30391Skarels * by UNIX convention in order that they be loaded and returned 410*30391Skarels * properly by the interrupt catching mechanism. */ 411*30391Skarels 412*30391Skarels register int unit; 413*30391Skarels 414*30391Skarels struct dga *dga; /* pointer to gate array structure */ 415*30391Skarels struct cpusw *cpup; /* pointer to the cpusw structure */ 416*30391Skarels 417*30391Skarels int *ptep; /* page table entry pointer */ 418*30391Skarels int vector; 419*30391Skarels 420*30391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 421*30391Skarels u_int mapix; 422*30391Skarels 423*30391Skarels /*--------------------------------------------------------------- 424*30391Skarels * calculate board unit number from I/O page register address */ 425*30391Skarels 426*30391Skarels unit = (int) (((int)reg >> 1) & 0x0007); 427*30391Skarels 428*30391Skarels /*--------------------------------------------------------------------------- 429*30391Skarels * QDSS regs must be mapped to Qbus memory space at a 64kb physical boundary. 430*30391Skarels * The Qbus memory space is mapped into the system memory space at config 431*30391Skarels * time. After config runs, "qmem[0]" (ubavar.h) holds the system virtual adrs 432*30391Skarels * of the start of Qbus memory. The Qbus memory page table is found via 433*30391Skarels * an array of pte ptrs called "QMEMmap[]" (ubavar.h) which is also loaded at 434*30391Skarels * config time. These are the variables used below to find a vacant 64kb 435*30391Skarels * boundary in Qbus memory, and load it's corresponding physical adrs into 436*30391Skarels * the QDSS's I/O page CSR. */ 437*30391Skarels 438*30391Skarels /* if this QDSS is NOT the console, then do init here.. */ 439*30391Skarels 440*30391Skarels if (v_consputc != qdputc || unit != 0) { 441*30391Skarels 442*30391Skarels /*------------------------- 443*30391Skarels * read QDSS config info */ 444*30391Skarels 445*30391Skarels qdflags[unit].config = *(u_short *)reg; 446*30391Skarels 447*30391Skarels /*------------------------------------ 448*30391Skarels * find an empty 64kb adrs boundary */ 449*30391Skarels 450*30391Skarels qdbase[unit] = (caddr_t) (qmem[0] + QMEMSIZE - CHUNK); 451*30391Skarels 452*30391Skarels /*---------------------------------------------------- 453*30391Skarels * find the cpusw entry that matches this machine. */ 454*30391Skarels 455*30391Skarels cpup = &cpusw[cpu]; 456*30391Skarels while ( !(BADADDR(qdbase[unit], sizeof(short))) ) 457*30391Skarels qdbase[unit] -= CHUNK; 458*30391Skarels 459*30391Skarels /*--------------------------------------------------- 460*30391Skarels * tell QDSS which Q memory address base to decode */ 461*30391Skarels 462*30391Skarels mapix = (int) (VTOP(qdbase[unit]) - VTOP(qmem[0])); 463*30391Skarels ptep = (int *) QMEMmap[0] + mapix; 464*30391Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 465*30391Skarels *(u_short *)reg = (u_short) ((int)phys_adr >> 16); 466*30391Skarels 467*30391Skarels /*----------------------------------------------------------- 468*30391Skarels * load QDSS adrs map with system addresses of device regs */ 469*30391Skarels 470*30391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 471*30391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 472*30391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 473*30391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 474*30391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 475*30391Skarels qdmap[unit].red = qdbase[unit] + RED; 476*30391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 477*30391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 478*30391Skarels 479*30391Skarels /* device init */ 480*30391Skarels 481*30391Skarels cursor[unit].x = 0; 482*30391Skarels cursor[unit].y = 0; 483*30391Skarels init_shared(unit); /* init shared memory */ 484*30391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 485*30391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 486*30391Skarels setup_input(unit); /* init the DUART */ 487*30391Skarels clear_qd_screen(unit); 488*30391Skarels ldfont(unit); /* load the console font */ 489*30391Skarels 490*30391Skarels /* once only: turn on sync */ 491*30391Skarels 492*30391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; 493*30391Skarels } 494*30391Skarels 495*30391Skarels /*-------------------------------------------------------------------------- 496*30391Skarels * the QDSS interrupts at HEX vectors xx0 (DMA) xx4 (ADDER) and xx8 (DUART). 497*30391Skarels * Therefore, we take three vectors from the vector pool, and then continue 498*30391Skarels * to take them until we get a xx0 HEX vector. The pool provides vectors 499*30391Skarels * in contiguous decending order. */ 500*30391Skarels 501*30391Skarels vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ 502*30391Skarels 503*30391Skarels while (vector & 0x0F) { /* if lo nibble != 0.. */ 504*30391Skarels vector = (uba_hd[0].uh_lastiv -= 4); /* ..take another vector */ 505*30391Skarels } 506*30391Skarels 507*30391Skarels /*--------------------------------------------------------- 508*30391Skarels * setup DGA to do a DMA interrupt (transfer count = 0) */ 509*30391Skarels 510*30391Skarels dga = (struct dga *) qdmap[unit].dga; 511*30391Skarels 512*30391Skarels dga->csr = (short) HALT; /* disable everything */ 513*30391Skarels dga->ivr = (short) vector; /* load intrpt base vector */ 514*30391Skarels dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ 515*30391Skarels dga->bytcnt_hi = (short) 0; 516*30391Skarels 517*30391Skarels /* turn on DMA interrupts */ 518*30391Skarels 519*30391Skarels dga->csr &= ~SET_DONE_FIFO; 520*30391Skarels dga->csr |= DMA_IE | DL_ENB; 521*30391Skarels 522*30391Skarels DELAY(20000); /* wait for the intrpt */ 523*30391Skarels 524*30391Skarels dga->csr = HALT; /* stop the wheels */ 525*30391Skarels 526*30391Skarels /*---------- 527*30391Skarels * exits */ 528*30391Skarels 529*30391Skarels if (cvec != vector) /* if vector != base vector.. */ 530*30391Skarels return(0); /* ..return = 'no device' */ 531*30391Skarels 532*30391Skarels return(sizeof(short)); /* return size of QDSS I/O page reg */ 533*30391Skarels 534*30391Skarels } /* qdprobe */ 535*30391Skarels 536*30391Skarels /***************************************************************** 537*30391Skarels * 538*30391Skarels * qdattach()... do the one-time initialization 539*30391Skarels * 540*30391Skarels ****************************************************************** 541*30391Skarels * 542*30391Skarels * calling convention: 543*30391Skarels * qdattach(ui); 544*30391Skarels * struct uba_device *ui; 545*30391Skarels * 546*30391Skarels * where: ui - pointer to the QDSS's uba_device structure 547*30391Skarels * 548*30391Skarels * side effects: none 549*30391Skarels * return: none 550*30391Skarels * 551*30391Skarels *************************/ 552*30391Skarels 553*30391Skarels qdattach(ui) 554*30391Skarels struct uba_device *ui; 555*30391Skarels { 556*30391Skarels register u_int unit; /* QDSS module # for this call */ 557*30391Skarels 558*30391Skarels unit = ui->ui_unit; /* get QDSS number */ 559*30391Skarels 560*30391Skarels /*---------------------------------- 561*30391Skarels * init "qdflags[]" for this QDSS */ 562*30391Skarels 563*30391Skarels qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ 564*30391Skarels qdflags[unit].mapped = 0; 565*30391Skarels qdflags[unit].kernel_loop = 0; 566*30391Skarels qdflags[unit].user_dma = 0; 567*30391Skarels qdflags[unit].curs_acc = ACC_OFF; 568*30391Skarels qdflags[unit].curs_thr = 128; 569*30391Skarels qdflags[unit].tab_res = 2; /* default tablet resolution factor */ 570*30391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 571*30391Skarels qdflags[unit].adder_ie = 0; 572*30391Skarels 573*30391Skarels /*---------------------------------------------------------------------- 574*30391Skarels * init structures used in kbd/mouse interrupt service. This code must 575*30391Skarels * come after the "init_shared()" routine has run since that routine inits 576*30391Skarels * the eq_header[unit] structure used here. */ 577*30391Skarels 578*30391Skarels /*-------------------------------------------- 579*30391Skarels * init the "latest mouse report" structure */ 580*30391Skarels 581*30391Skarels last_rep[unit].state = 0; 582*30391Skarels last_rep[unit].dx = 0; 583*30391Skarels last_rep[unit].dy = 0; 584*30391Skarels last_rep[unit].bytcnt = 0; 585*30391Skarels 586*30391Skarels /*------------------------------------------------ 587*30391Skarels * init the event queue (except mouse position) */ 588*30391Skarels 589*30391Skarels eq_header[unit]->header.events = (struct _vs_event *) 590*30391Skarels ((int)eq_header[unit] 591*30391Skarels + sizeof(struct qdinput)); 592*30391Skarels 593*30391Skarels eq_header[unit]->header.size = MAXEVENTS; 594*30391Skarels eq_header[unit]->header.head = 0; 595*30391Skarels eq_header[unit]->header.tail = 0; 596*30391Skarels 597*30391Skarels /*------------------------------------------ 598*30391Skarels * init single process access lock switch */ 599*30391Skarels 600*30391Skarels one_only[unit] = 0; 601*30391Skarels 602*30391Skarels } /* qdattach */ 603*30391Skarels 604*30391Skarels /*************************************************************** 605*30391Skarels * 606*30391Skarels * qdopen()... open a minor device 607*30391Skarels * 608*30391Skarels **************************************************************** 609*30391Skarels * 610*30391Skarels * calling convention: qdopen(dev, flag); 611*30391Skarels * dev_t dev; 612*30391Skarels * int flag; 613*30391Skarels * 614*30391Skarels * side effects: none 615*30391Skarels * 616*30391Skarels *********************/ 617*30391Skarels 618*30391Skarels qdopen(dev, flag) 619*30391Skarels dev_t dev; 620*30391Skarels int flag; 621*30391Skarels { 622*30391Skarels register struct uba_device *ui; /* ptr to uba structures */ 623*30391Skarels register struct dga *dga; /* ptr to gate array struct */ 624*30391Skarels register struct tty *tp; 625*30391Skarels 626*30391Skarels struct adder *adder; 627*30391Skarels struct duart *duart; 628*30391Skarels 629*30391Skarels u_int unit; 630*30391Skarels u_int minor_dev; 631*30391Skarels int s; 632*30391Skarels 633*30391Skarels minor_dev = minor(dev); /* get QDSS minor device number */ 634*30391Skarels unit = minor_dev >> 2; 635*30391Skarels 636*30391Skarels /*--------------------------------- 637*30391Skarels * check for illegal conditions */ 638*30391Skarels 639*30391Skarels ui = qdinfo[unit]; /* get ptr to QDSS device struct */ 640*30391Skarels 641*30391Skarels if (ui == 0 || ui->ui_alive == 0) 642*30391Skarels return(ENXIO); /* no such device or address */ 643*30391Skarels 644*30391Skarels /*-------------- 645*30391Skarels * init stuff */ 646*30391Skarels 647*30391Skarels adder = (struct adder *) qdmap[unit].adder; 648*30391Skarels duart = (struct duart *) qdmap[unit].duart; 649*30391Skarels dga = (struct dga *) qdmap[unit].dga; 650*30391Skarels 651*30391Skarels /*------------------------------------ 652*30391Skarels * if this is the graphic device... */ 653*30391Skarels 654*30391Skarels if ((minor_dev & 0x03) == 2) { 655*30391Skarels 656*30391Skarels if (one_only[unit] != 0) 657*30391Skarels return(EBUSY); 658*30391Skarels else 659*30391Skarels one_only[unit] = 1; 660*30391Skarels 661*30391Skarels qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ 662*30391Skarels 663*30391Skarels /* enble kbd & mouse intrpts in DUART mask reg */ 664*30391Skarels 665*30391Skarels qdflags[unit].duart_imask |= 0x22; 666*30391Skarels duart->imask = qdflags[unit].duart_imask; 667*30391Skarels 668*30391Skarels /*------------------------------------------------------------------ 669*30391Skarels * if the open call is to the console or the alternate console... */ 670*30391Skarels 671*30391Skarels } else if ((minor_dev & 0x03) != 2) { 672*30391Skarels 673*30391Skarels qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ 674*30391Skarels dga->csr |= CURS_ENB; 675*30391Skarels 676*30391Skarels qdflags[unit].duart_imask |= 0x02; 677*30391Skarels duart->imask = qdflags[unit].duart_imask; 678*30391Skarels 679*30391Skarels /*------------------------------- 680*30391Skarels * some setup for tty handling */ 681*30391Skarels 682*30391Skarels tp = &qd_tty[minor_dev]; 683*30391Skarels 684*30391Skarels tp->t_addr = ui->ui_addr; 685*30391Skarels tp->t_oproc = qdstart; 686*30391Skarels 687*30391Skarels if ((tp->t_state & TS_ISOPEN) == 0) { 688*30391Skarels 689*30391Skarels ttychars(tp); 690*30391Skarels tp->t_state = TS_ISOPEN | TS_CARR_ON; 691*30391Skarels tp->t_ispeed = B9600; 692*30391Skarels tp->t_ospeed = B9600; 693*30391Skarels 694*30391Skarels if( (minor_dev & 0x03) == 0 ) 695*30391Skarels tp->t_flags = XTABS|EVENP|ECHO|CRMOD; 696*30391Skarels else 697*30391Skarels tp->t_flags = RAW; 698*30391Skarels } 699*30391Skarels 700*30391Skarels /*---------------------------------------- 701*30391Skarels * enable intrpts, open line discipline */ 702*30391Skarels 703*30391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 704*30391Skarels return ((*linesw[tp->t_line].l_open)(dev, tp)); 705*30391Skarels } 706*30391Skarels 707*30391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 708*30391Skarels return(0); 709*30391Skarels 710*30391Skarels } /* qdopen */ 711*30391Skarels 712*30391Skarels /*************************************************************** 713*30391Skarels * 714*30391Skarels * qdclose()... clean up on the way out 715*30391Skarels * 716*30391Skarels **************************************************************** 717*30391Skarels * 718*30391Skarels * calling convention: qdclose(); 719*30391Skarels * 720*30391Skarels * side effects: none 721*30391Skarels * 722*30391Skarels * return: none 723*30391Skarels * 724*30391Skarels *********************/ 725*30391Skarels 726*30391Skarels qdclose(dev, flag) 727*30391Skarels dev_t dev; 728*30391Skarels int flag; 729*30391Skarels { 730*30391Skarels register struct tty *tp; 731*30391Skarels register struct qdmap *qd; 732*30391Skarels register int *ptep; 733*30391Skarels int i; /* SIGNED index */ 734*30391Skarels 735*30391Skarels struct dga *dga; /* gate array register map pointer */ 736*30391Skarels struct duart *duart; 737*30391Skarels struct adder *adder; 738*30391Skarels 739*30391Skarels u_int unit; 740*30391Skarels u_int minor_dev; 741*30391Skarels u_int mapix; 742*30391Skarels 743*30391Skarels minor_dev = minor(dev); /* get minor device number */ 744*30391Skarels unit = minor_dev >> 2; /* get QDSS number */ 745*30391Skarels qd = &qdmap[unit]; 746*30391Skarels 747*30391Skarels /*------------------------------------ 748*30391Skarels * if this is the graphic device... */ 749*30391Skarels 750*30391Skarels if ((minor_dev & 0x03) == 2) { 751*30391Skarels 752*30391Skarels /*----------------- 753*30391Skarels * unlock driver */ 754*30391Skarels 755*30391Skarels if (one_only[unit] != 1) 756*30391Skarels return(EBUSY); 757*30391Skarels else 758*30391Skarels one_only[unit] = 0; 759*30391Skarels 760*30391Skarels /*---------------------------- 761*30391Skarels * re-protect device memory */ 762*30391Skarels 763*30391Skarels if (qdflags[unit].mapped & MAPDEV) { 764*30391Skarels 765*30391Skarels /*---------------- 766*30391Skarels * TEMPLATE RAM */ 767*30391Skarels 768*30391Skarels mapix = VTOP((int)qd->template) - VTOP(qmem[0]); 769*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 770*30391Skarels 771*30391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 772*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 773*30391Skarels 774*30391Skarels /*--------- 775*30391Skarels * ADDER */ 776*30391Skarels 777*30391Skarels mapix = VTOP((int)qd->adder) - VTOP(qmem[0]); 778*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 779*30391Skarels 780*30391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 781*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 782*30391Skarels 783*30391Skarels /*-------------- 784*30391Skarels * COLOR MAPS */ 785*30391Skarels 786*30391Skarels mapix = VTOP((int)qd->red) - VTOP(qmem[0]); 787*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 788*30391Skarels 789*30391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 790*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 791*30391Skarels } 792*30391Skarels 793*30391Skarels /*---------------------------------------------------- 794*30391Skarels * re-protect DMA buffer and free the map registers */ 795*30391Skarels 796*30391Skarels if (qdflags[unit].mapped & MAPDMA) { 797*30391Skarels 798*30391Skarels dga = (struct dga *) qdmap[unit].dga; 799*30391Skarels adder = (struct adder *) qdmap[unit].adder; 800*30391Skarels 801*30391Skarels dga->csr &= ~DMA_IE; 802*30391Skarels dga->csr &= ~0x0600; /* kill DMA */ 803*30391Skarels adder->command = CANCEL; 804*30391Skarels 805*30391Skarels /* if DMA was running, flush spurious intrpt */ 806*30391Skarels 807*30391Skarels if (dga->bytcnt_lo != 0) { 808*30391Skarels dga->bytcnt_lo = 0; 809*30391Skarels dga->bytcnt_hi = 0; 810*30391Skarels DMA_SETIGNORE(DMAheader[unit]); 811*30391Skarels dga->csr |= DMA_IE; 812*30391Skarels dga->csr &= ~DMA_IE; 813*30391Skarels } 814*30391Skarels 815*30391Skarels ptep = (int *) 816*30391Skarels ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); 817*30391Skarels 818*30391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 819*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 820*30391Skarels 821*30391Skarels ubarelse(0, &Qbus_unmap[unit]); 822*30391Skarels } 823*30391Skarels 824*30391Skarels /*--------------------------------------- 825*30391Skarels * re-protect 1K (2 pages) event queue */ 826*30391Skarels 827*30391Skarels if (qdflags[unit].mapped & MAPEQ) { 828*30391Skarels 829*30391Skarels ptep = (int *) 830*30391Skarels ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); 831*30391Skarels 832*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 833*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 834*30391Skarels } 835*30391Skarels 836*30391Skarels /*------------------------------------------------------------ 837*30391Skarels * re-protect scroll param area and disable scroll intrpts */ 838*30391Skarels 839*30391Skarels if (qdflags[unit].mapped & MAPSCR) { 840*30391Skarels 841*30391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 842*30391Skarels + (mfpr(SBR) | 0x80000000)); 843*30391Skarels 844*30391Skarels /* re-protect 512 scroll param area */ 845*30391Skarels 846*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 847*30391Skarels 848*30391Skarels adder = (struct adder *) qdmap[unit].adder; 849*30391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 850*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 851*30391Skarels } 852*30391Skarels 853*30391Skarels /*----------------------------------------------------------- 854*30391Skarels * re-protect color map write buffer area and kill intrpts */ 855*30391Skarels 856*30391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 857*30391Skarels 858*30391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 859*30391Skarels + (mfpr(SBR) | 0x80000000)); 860*30391Skarels 861*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 862*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 863*30391Skarels 864*30391Skarels color_buf[unit]->status = 0; 865*30391Skarels 866*30391Skarels adder = (struct adder *) qdmap[unit].adder; 867*30391Skarels qdflags[unit].adder_ie &= ~VSYNC; 868*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 869*30391Skarels } 870*30391Skarels 871*30391Skarels /*----------------------------------- 872*30391Skarels * flag that everthing is unmapped */ 873*30391Skarels 874*30391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 875*30391Skarels qdflags[unit].mapped = 0; /* flag everything now unmapped */ 876*30391Skarels qdflags[unit].inuse &= ~GRAPHIC_DEV; 877*30391Skarels qdflags[unit].curs_acc = ACC_OFF; 878*30391Skarels qdflags[unit].curs_thr = 128; 879*30391Skarels 880*30391Skarels /*--------------------- 881*30391Skarels * restore the console */ 882*30391Skarels 883*30391Skarels dga = (struct dga *) qdmap[unit].dga; 884*30391Skarels adder = (struct adder *) qdmap[unit].adder; 885*30391Skarels 886*30391Skarels dga->csr &= ~DMA_IE; 887*30391Skarels dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ 888*30391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 889*30391Skarels adder->command = CANCEL; 890*30391Skarels 891*30391Skarels /* if DMA was running, flush spurious intrpt */ 892*30391Skarels 893*30391Skarels if (dga->bytcnt_lo != 0) { 894*30391Skarels dga->bytcnt_lo = 0; 895*30391Skarels dga->bytcnt_hi = 0; 896*30391Skarels DMA_SETIGNORE(DMAheader[unit]); 897*30391Skarels dga->csr |= DMA_IE; 898*30391Skarels dga->csr &= ~DMA_IE; 899*30391Skarels } 900*30391Skarels 901*30391Skarels init_shared(unit); /* init shared memory */ 902*30391Skarels setup_dragon(unit); /* init ADDER/VIPER */ 903*30391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 904*30391Skarels setup_input(unit); /* init the DUART */ 905*30391Skarels ldfont(unit); 906*30391Skarels cursor[unit].x = 0; 907*30391Skarels cursor[unit].y = 0; 908*30391Skarels 909*30391Skarels /* shut off the mouse rcv intrpt and turn on kbd intrpts */ 910*30391Skarels 911*30391Skarels duart = (struct duart *) qdmap[unit].duart; 912*30391Skarels qdflags[unit].duart_imask &= ~(0x20); 913*30391Skarels qdflags[unit].duart_imask |= 0x02; 914*30391Skarels duart->imask = qdflags[unit].duart_imask; 915*30391Skarels 916*30391Skarels /*----------------------------------------- 917*30391Skarels * shut off interrupts if all is closed */ 918*30391Skarels 919*30391Skarels if (!(qdflags[unit].inuse & (CONS_DEV | ALTCONS_DEV))) { 920*30391Skarels 921*30391Skarels dga = (struct dga *) qdmap[unit].dga; 922*30391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 923*30391Skarels } 924*30391Skarels } 925*30391Skarels 926*30391Skarels /*---------------------------------------------------- 927*30391Skarels * if this is the console or the alternate console */ 928*30391Skarels 929*30391Skarels else { 930*30391Skarels 931*30391Skarels tp = &qd_tty[minor_dev]; 932*30391Skarels 933*30391Skarels (*linesw[tp->t_line].l_close)(tp); 934*30391Skarels ttyclose(tp); 935*30391Skarels 936*30391Skarels tp->t_state = 0; 937*30391Skarels 938*30391Skarels qdflags[unit].inuse &= ~CONS_DEV; 939*30391Skarels 940*30391Skarels /*------------------------------------------------- 941*30391Skarels * if graphics device is closed, kill interrupts */ 942*30391Skarels 943*30391Skarels if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { 944*30391Skarels dga = (struct dga *) qdmap[unit].dga; 945*30391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 946*30391Skarels } 947*30391Skarels } 948*30391Skarels 949*30391Skarels /*-------- 950*30391Skarels * exit */ 951*30391Skarels 952*30391Skarels return(0); 953*30391Skarels 954*30391Skarels } /* qdclose */ 955*30391Skarels 956*30391Skarels /*************************************************************** 957*30391Skarels * 958*30391Skarels * qdioctl()... provide QDSS control services 959*30391Skarels * 960*30391Skarels **************************************************************** 961*30391Skarels * 962*30391Skarels * calling convention: qdioctl(dev, cmd, datap, flags); 963*30391Skarels * 964*30391Skarels * where: dev - the major/minor device number 965*30391Skarels * cmd - the user-passed command argument 966*30391Skarels * datap - ptr to user input buff (128 bytes max) 967*30391Skarels * flags - "f_flags" from "struct file" in file.h 968*30391Skarels * 969*30391Skarels * 970*30391Skarels * - here is the format for the input "cmd" argument 971*30391Skarels * 972*30391Skarels * 31 29 28 23 22 16 15 8 7 0 973*30391Skarels * +----------------------------------------------------------------+ 974*30391Skarels * |I/O type| | buff length | device ID char | user command | 975*30391Skarels * +----------------------------------------------------------------+ 976*30391Skarels * 977*30391Skarels * Return data is in the data buffer pointed to by "datap" input spec 978*30391Skarels * 979*30391Skarels *********************/ 980*30391Skarels 981*30391Skarels qdioctl(dev, cmd, datap, flags) 982*30391Skarels dev_t dev; 983*30391Skarels int cmd; 984*30391Skarels caddr_t datap; 985*30391Skarels int flags; 986*30391Skarels { 987*30391Skarels register int *ptep; /* page table entry pointer */ 988*30391Skarels register int mapix; /* QMEMmap[] page table index */ 989*30391Skarels register struct _vs_event *event; 990*30391Skarels register struct tty *tp; 991*30391Skarels 992*30391Skarels struct qdmap *qd; /* pointer to device map struct */ 993*30391Skarels struct dga *dga; /* Gate Array reg structure pntr */ 994*30391Skarels struct duart *duart; /* DUART reg structure pointer */ 995*30391Skarels struct adder *adder; /* ADDER reg structure pointer */ 996*30391Skarels 997*30391Skarels struct prgkbd *cmdbuf; 998*30391Skarels struct prg_cursor *curs; 999*30391Skarels struct _vs_cursor *pos; 1000*30391Skarels 1001*30391Skarels u_int unit = minor(dev) >> 2; /* number of caller's QDSS */ 1002*30391Skarels u_int minor_dev = minor(dev); 1003*30391Skarels struct uba_device *ui = qdinfo[unit]; 1004*30391Skarels struct qd_softc *sc = &qd_softc[ui->ui_unit]; 1005*30391Skarels struct devget *devget; 1006*30391Skarels 1007*30391Skarels int error; 1008*30391Skarels int s; 1009*30391Skarels 1010*30391Skarels int i; /* SIGNED index */ 1011*30391Skarels int sbr; /* SBR variable (you silly boy) */ 1012*30391Skarels u_int ix; 1013*30391Skarels 1014*30391Skarels short status; 1015*30391Skarels short *shortp; /* generic pointer to a short */ 1016*30391Skarels char *chrp; /* generic character pointer */ 1017*30391Skarels 1018*30391Skarels short *temp; /* a pointer to template RAM */ 1019*30391Skarels 1020*30391Skarels /*----------------------------------------- 1021*30391Skarels * service graphic device ioctl commands */ 1022*30391Skarels 1023*30391Skarels switch (cmd) { 1024*30391Skarels 1025*30391Skarels /*------------------------------------------------- 1026*30391Skarels * extract the oldest event from the event queue */ 1027*30391Skarels 1028*30391Skarels case QD_GETEVENT: 1029*30391Skarels 1030*30391Skarels if (ISEMPTY(eq_header[unit])) { 1031*30391Skarels event = (struct _vs_event *) datap; 1032*30391Skarels event->vse_device = VSE_NULL; 1033*30391Skarels break; 1034*30391Skarels } 1035*30391Skarels 1036*30391Skarels event = (struct _vs_event *) GETBEGIN(eq_header[unit]); 1037*30391Skarels s = spl5(); 1038*30391Skarels GETEND(eq_header[unit]); 1039*30391Skarels splx(s); 1040*30391Skarels bcopy(event, datap, sizeof(struct _vs_event)); 1041*30391Skarels break; 1042*30391Skarels 1043*30391Skarels /*------------------------------------------------------- 1044*30391Skarels * init the dragon stuff, DUART, and driver variables */ 1045*30391Skarels 1046*30391Skarels case QD_RESET: 1047*30391Skarels 1048*30391Skarels init_shared(unit); /* init shared memory */ 1049*30391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 1050*30391Skarels clear_qd_screen(unit); 1051*30391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 1052*30391Skarels ldfont(unit); /* load the console font */ 1053*30391Skarels setup_input(unit); /* init the DUART */ 1054*30391Skarels break; 1055*30391Skarels 1056*30391Skarels /*---------------------------------------- 1057*30391Skarels * init the DUART and driver variables */ 1058*30391Skarels 1059*30391Skarels case QD_SET: 1060*30391Skarels 1061*30391Skarels init_shared(unit); 1062*30391Skarels setup_input(unit); 1063*30391Skarels break; 1064*30391Skarels 1065*30391Skarels /*--------------------------------------------------------------- 1066*30391Skarels * clear the QDSS screen. (NOTE that this reinits the dragon) */ 1067*30391Skarels 1068*30391Skarels case QD_CLRSCRN: 1069*30391Skarels 1070*30391Skarels setup_dragon(unit); 1071*30391Skarels clear_qd_screen(unit); 1072*30391Skarels break; 1073*30391Skarels 1074*30391Skarels /*------------------------------------ 1075*30391Skarels * load a cursor into template RAM */ 1076*30391Skarels 1077*30391Skarels case QD_WTCURSOR: 1078*30391Skarels 1079*30391Skarels ldcursor(unit, datap); 1080*30391Skarels break; 1081*30391Skarels 1082*30391Skarels case QD_RDCURSOR: 1083*30391Skarels 1084*30391Skarels temp = (short *) qdmap[unit].template; 1085*30391Skarels 1086*30391Skarels /* cursor is 32 WORDS from the end of the 8k WORD... 1087*30391Skarels * ...template space */ 1088*30391Skarels 1089*30391Skarels temp += (8 * 1024) - 32; 1090*30391Skarels 1091*30391Skarels for (i = 0; i < 32; ++i, datap += sizeof(short)) 1092*30391Skarels *(short *)datap = *temp++; 1093*30391Skarels break; 1094*30391Skarels 1095*30391Skarels /*------------------------------ 1096*30391Skarels * position the mouse cursor */ 1097*30391Skarels 1098*30391Skarels case QD_POSCURSOR: 1099*30391Skarels 1100*30391Skarels dga = (struct dga *) qdmap[unit].dga; 1101*30391Skarels pos = (struct _vs_cursor *) datap; 1102*30391Skarels s = spl5(); 1103*30391Skarels dga->x_cursor = TRANX(pos->x); 1104*30391Skarels dga->y_cursor = TRANY(pos->y); 1105*30391Skarels eq_header[unit]->curs_pos.x = pos->x; 1106*30391Skarels eq_header[unit]->curs_pos.y = pos->y; 1107*30391Skarels splx(s); 1108*30391Skarels break; 1109*30391Skarels 1110*30391Skarels /*-------------------------------------- 1111*30391Skarels * set the cursor acceleration factor */ 1112*30391Skarels 1113*30391Skarels case QD_PRGCURSOR: 1114*30391Skarels 1115*30391Skarels curs = (struct prg_cursor *) datap; 1116*30391Skarels s = spl5(); 1117*30391Skarels qdflags[unit].curs_acc = curs->acc_factor; 1118*30391Skarels qdflags[unit].curs_thr = curs->threshold; 1119*30391Skarels splx(s); 1120*30391Skarels break; 1121*30391Skarels 1122*30391Skarels /*--------------------------------------- 1123*30391Skarels * enable 'user write' to device pages */ 1124*30391Skarels 1125*30391Skarels case QD_MAPDEVICE: 1126*30391Skarels 1127*30391Skarels /*-------------- 1128*30391Skarels * init stuff */ 1129*30391Skarels 1130*30391Skarels qdflags[unit].mapped |= MAPDEV; 1131*30391Skarels qd = (struct qdmap *) &qdmap[unit]; 1132*30391Skarels 1133*30391Skarels /*------------------------------------- 1134*30391Skarels * enable user write to template RAM */ 1135*30391Skarels 1136*30391Skarels mapix = VTOP((int)qd->template) - VTOP(qmem[0]); 1137*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 1138*30391Skarels 1139*30391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 1140*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1141*30391Skarels 1142*30391Skarels /*---------------------------------- 1143*30391Skarels * enable user write to registers */ 1144*30391Skarels 1145*30391Skarels mapix = VTOP((int)qd->adder) - VTOP(qmem[0]); 1146*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 1147*30391Skarels 1148*30391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 1149*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1150*30391Skarels 1151*30391Skarels /*----------------------------------- 1152*30391Skarels * enable user write to color maps */ 1153*30391Skarels 1154*30391Skarels mapix = VTOP((int)qd->red) - VTOP(qmem[0]); 1155*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 1156*30391Skarels 1157*30391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 1158*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1159*30391Skarels 1160*30391Skarels /*------------------------------ 1161*30391Skarels * enable user write to DUART */ 1162*30391Skarels 1163*30391Skarels mapix = VTOP((int)qd->duart) - VTOP(qmem[0]); 1164*30391Skarels ptep = (int *)(QMEMmap[0] + mapix); 1165*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ 1166*30391Skarels 1167*30391Skarels mtpr(TBIA, 0); /* smash CPU's translation buffer */ 1168*30391Skarels 1169*30391Skarels /*------------------------------------------ 1170*30391Skarels * stuff qdmap structure in return buffer */ 1171*30391Skarels 1172*30391Skarels bcopy(qd, datap, sizeof(struct qdmap)); 1173*30391Skarels break; 1174*30391Skarels 1175*30391Skarels /*------------------------------------- 1176*30391Skarels * do setup for DMA by user process */ 1177*30391Skarels 1178*30391Skarels case QD_MAPIOBUF: 1179*30391Skarels 1180*30391Skarels /*------------------------------------------------ 1181*30391Skarels * set 'user write enable' bits for DMA buffer */ 1182*30391Skarels 1183*30391Skarels qdflags[unit].mapped |= MAPDMA; 1184*30391Skarels 1185*30391Skarels ptep = (int *) ((VTOP(DMAheader[unit]) * 4) 1186*30391Skarels + (mfpr(SBR) | 0x80000000)); 1187*30391Skarels 1188*30391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 1189*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1190*30391Skarels 1191*30391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 1192*30391Skarels 1193*30391Skarels /*------------------------------------- 1194*30391Skarels * set up QBUS map registers for DMA */ 1195*30391Skarels 1196*30391Skarels DMAheader[unit]->QBAreg = 1197*30391Skarels uballoc(0, DMAheader[unit], DMAbuf_size, 0); 1198*30391Skarels 1199*30391Skarels if (DMAheader[unit]->QBAreg == 0) 1200*30391Skarels mprintf("\nqd%d: qdioctl: QBA setup error", unit); 1201*30391Skarels 1202*30391Skarels Qbus_unmap[unit] = DMAheader[unit]->QBAreg; 1203*30391Skarels DMAheader[unit]->QBAreg &= 0x3FFFF; 1204*30391Skarels 1205*30391Skarels /*---------------------- 1206*30391Skarels * return I/O buf adr */ 1207*30391Skarels 1208*30391Skarels *(int *)datap = (int) DMAheader[unit]; 1209*30391Skarels break; 1210*30391Skarels 1211*30391Skarels /*---------------------------------------------------------------- 1212*30391Skarels * map the shared scroll param area and enable scroll interpts */ 1213*30391Skarels 1214*30391Skarels case QD_MAPSCROLL: 1215*30391Skarels 1216*30391Skarels qdflags[unit].mapped |= MAPSCR; 1217*30391Skarels 1218*30391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 1219*30391Skarels + (mfpr(SBR) | 0x80000000)); 1220*30391Skarels 1221*30391Skarels /* allow user write to scroll area */ 1222*30391Skarels 1223*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1224*30391Skarels 1225*30391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 1226*30391Skarels 1227*30391Skarels scroll[unit]->status = 0; 1228*30391Skarels 1229*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1230*30391Skarels 1231*30391Skarels qdflags[unit].adder_ie |= FRAME_SYNC; 1232*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 1233*30391Skarels 1234*30391Skarels /* return scroll area address */ 1235*30391Skarels 1236*30391Skarels *(int *)datap = (int) scroll[unit]; 1237*30391Skarels break; 1238*30391Skarels 1239*30391Skarels /*------------------------------------------------------------- 1240*30391Skarels * unmap shared scroll param area and disable scroll intrpts */ 1241*30391Skarels 1242*30391Skarels case QD_UNMAPSCROLL: 1243*30391Skarels 1244*30391Skarels if (qdflags[unit].mapped & MAPSCR) { 1245*30391Skarels 1246*30391Skarels qdflags[unit].mapped &= ~MAPSCR; 1247*30391Skarels 1248*30391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 1249*30391Skarels + (mfpr(SBR) | 0x80000000)); 1250*30391Skarels 1251*30391Skarels /* re-protect 512 scroll param area */ 1252*30391Skarels 1253*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 1254*30391Skarels 1255*30391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 1256*30391Skarels 1257*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1258*30391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 1259*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 1260*30391Skarels } 1261*30391Skarels break; 1262*30391Skarels 1263*30391Skarels /*----------------------------------------------------------- 1264*30391Skarels * map shared color map write buf and turn on vsync intrpt */ 1265*30391Skarels 1266*30391Skarels case QD_MAPCOLOR: 1267*30391Skarels 1268*30391Skarels qdflags[unit].mapped |= MAPCOLOR; 1269*30391Skarels 1270*30391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 1271*30391Skarels + (mfpr(SBR) | 0x80000000)); 1272*30391Skarels 1273*30391Skarels /* allow user write to color map write buffer */ 1274*30391Skarels 1275*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1276*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1277*30391Skarels 1278*30391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 1279*30391Skarels 1280*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1281*30391Skarels 1282*30391Skarels qdflags[unit].adder_ie |= VSYNC; 1283*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 1284*30391Skarels 1285*30391Skarels /* return scroll area address */ 1286*30391Skarels 1287*30391Skarels *(int *)datap = (int) color_buf[unit]; 1288*30391Skarels break; 1289*30391Skarels 1290*30391Skarels /*-------------------------------------------------------------- 1291*30391Skarels * unmap shared color map write buffer and kill VSYNC intrpts */ 1292*30391Skarels 1293*30391Skarels case QD_UNMAPCOLOR: 1294*30391Skarels 1295*30391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 1296*30391Skarels 1297*30391Skarels qdflags[unit].mapped &= ~MAPCOLOR; 1298*30391Skarels 1299*30391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 1300*30391Skarels + (mfpr(SBR) | 0x80000000)); 1301*30391Skarels 1302*30391Skarels /* re-protect color map write buffer */ 1303*30391Skarels 1304*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 1305*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 1306*30391Skarels 1307*30391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 1308*30391Skarels 1309*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1310*30391Skarels 1311*30391Skarels qdflags[unit].adder_ie &= ~VSYNC; 1312*30391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 1313*30391Skarels } 1314*30391Skarels break; 1315*30391Skarels 1316*30391Skarels /*--------------------------------------------- 1317*30391Skarels * give user write access to the event queue */ 1318*30391Skarels 1319*30391Skarels case QD_MAPEVENT: 1320*30391Skarels 1321*30391Skarels qdflags[unit].mapped |= MAPEQ; 1322*30391Skarels 1323*30391Skarels ptep = (int *) ((VTOP(eq_header[unit]) * 4) 1324*30391Skarels + (mfpr(SBR) | 0x80000000)); 1325*30391Skarels 1326*30391Skarels /* allow user write to 1K event queue */ 1327*30391Skarels 1328*30391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1329*30391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 1330*30391Skarels 1331*30391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 1332*30391Skarels 1333*30391Skarels /* return event queue address */ 1334*30391Skarels 1335*30391Skarels *(int *)datap = (int) eq_header[unit]; 1336*30391Skarels break; 1337*30391Skarels 1338*30391Skarels /*----------------------------------------------- 1339*30391Skarels * pass caller's programming commands to LK201 */ 1340*30391Skarels 1341*30391Skarels case QD_PRGKBD: 1342*30391Skarels 1343*30391Skarels duart = (struct duart *) qdmap[unit].duart; 1344*30391Skarels cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ 1345*30391Skarels 1346*30391Skarels /*---------------- 1347*30391Skarels * send command */ 1348*30391Skarels 1349*30391Skarels for (i = 1000; i > 0; --i) { 1350*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 1351*30391Skarels duart->dataA = cmdbuf->cmd; 1352*30391Skarels break; 1353*30391Skarels } 1354*30391Skarels } 1355*30391Skarels 1356*30391Skarels if (i == 0) { 1357*30391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [1]", unit); 1358*30391Skarels break; 1359*30391Skarels } 1360*30391Skarels 1361*30391Skarels /*---------------- 1362*30391Skarels * send param1? */ 1363*30391Skarels 1364*30391Skarels if (cmdbuf->cmd & LAST_PARAM) 1365*30391Skarels break; 1366*30391Skarels 1367*30391Skarels for (i = 1000; i > 0; --i) { 1368*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 1369*30391Skarels duart->dataA = cmdbuf->param1; 1370*30391Skarels break; 1371*30391Skarels } 1372*30391Skarels } 1373*30391Skarels 1374*30391Skarels if (i == 0) { 1375*30391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [2]", unit); 1376*30391Skarels break; 1377*30391Skarels } 1378*30391Skarels 1379*30391Skarels /*---------------- 1380*30391Skarels * send param2? */ 1381*30391Skarels 1382*30391Skarels if (cmdbuf->param1 & LAST_PARAM) 1383*30391Skarels break; 1384*30391Skarels 1385*30391Skarels for (i = 1000; i > 0; --i) { 1386*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 1387*30391Skarels duart->dataA = cmdbuf->param2; 1388*30391Skarels break; 1389*30391Skarels } 1390*30391Skarels } 1391*30391Skarels 1392*30391Skarels if (i == 0) { 1393*30391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [3]", unit); 1394*30391Skarels break; 1395*30391Skarels } 1396*30391Skarels 1397*30391Skarels break; 1398*30391Skarels 1399*30391Skarels /*---------------------------------------------------- 1400*30391Skarels * pass caller's programming commands to the mouse */ 1401*30391Skarels 1402*30391Skarels case QD_PRGMOUSE: 1403*30391Skarels 1404*30391Skarels duart = (struct duart *) qdmap[unit].duart; 1405*30391Skarels 1406*30391Skarels for (i = 1000; i > 0; --i) { 1407*30391Skarels if ((status = duart->statusB) & XMT_RDY) { 1408*30391Skarels duart->dataB = *datap; 1409*30391Skarels break; 1410*30391Skarels } 1411*30391Skarels } 1412*30391Skarels 1413*30391Skarels if (i == 0) { 1414*30391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [4]", unit); 1415*30391Skarels } 1416*30391Skarels 1417*30391Skarels break; 1418*30391Skarels 1419*30391Skarels /*---------------------------------------------- 1420*30391Skarels * get QDSS configuration word and return it */ 1421*30391Skarels 1422*30391Skarels case QD_RDCONFIG: 1423*30391Skarels 1424*30391Skarels *(short *)datap = qdflags[unit].config; 1425*30391Skarels break; 1426*30391Skarels 1427*30391Skarels /*-------------------------------------------------------------- 1428*30391Skarels * re-route kernel console messages to the alternate console */ 1429*30391Skarels 1430*30391Skarels case QD_KERN_LOOP: 1431*30391Skarels 1432*30391Skarels qdflags[unit].kernel_loop = -1; 1433*30391Skarels break; 1434*30391Skarels 1435*30391Skarels case QD_KERN_UNLOOP: 1436*30391Skarels 1437*30391Skarels qdflags[unit].kernel_loop = 0; 1438*30391Skarels break; 1439*30391Skarels 1440*30391Skarels /*---------------------- 1441*30391Skarels * program the tablet */ 1442*30391Skarels 1443*30391Skarels case QD_PRGTABLET: 1444*30391Skarels 1445*30391Skarels duart = (struct duart *) qdmap[unit].duart; 1446*30391Skarels 1447*30391Skarels for (i = 1000; i > 0; --i) { 1448*30391Skarels if ((status = duart->statusB) & XMT_RDY) { 1449*30391Skarels duart->dataB = *datap; 1450*30391Skarels break; 1451*30391Skarels } 1452*30391Skarels } 1453*30391Skarels 1454*30391Skarels if (i == 0) { 1455*30391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [5]", unit); 1456*30391Skarels } 1457*30391Skarels 1458*30391Skarels break; 1459*30391Skarels 1460*30391Skarels /*----------------------------------------------- 1461*30391Skarels * program the tablet report resolution factor */ 1462*30391Skarels 1463*30391Skarels case QD_PRGTABRES: 1464*30391Skarels 1465*30391Skarels qdflags[unit].tab_res = *(short *)datap; 1466*30391Skarels break; 1467*30391Skarels 1468*30391Skarels case DEVIOCGET: /* device status */ 1469*30391Skarels devget = (struct devget *)datap; 1470*30391Skarels bzero(devget,sizeof(struct devget)); 1471*30391Skarels devget->category = DEV_TERMINAL; 1472*30391Skarels devget->bus = DEV_QB; 1473*30391Skarels bcopy(DEV_VCB02,devget->interface, 1474*30391Skarels strlen(DEV_VCB02)); 1475*30391Skarels bcopy(DEV_VR290,devget->device, 1476*30391Skarels strlen(DEV_VR290)); /* terminal */ 1477*30391Skarels devget->adpt_num = ui->ui_adpt; /* which adapter*/ 1478*30391Skarels devget->nexus_num = ui->ui_nexus; /* which nexus */ 1479*30391Skarels devget->bus_num = ui->ui_ubanum; /* which QB */ 1480*30391Skarels devget->ctlr_num = unit; /* which interf.*/ 1481*30391Skarels devget->slave_num = unit; /* which line */ 1482*30391Skarels bcopy(ui->ui_driver->ud_dname, 1483*30391Skarels devget->dev_name, 1484*30391Skarels strlen(ui->ui_driver->ud_dname)); /* Ultrix "qd" */ 1485*30391Skarels devget->unit_num = unit; /* qd line? */ 1486*30391Skarels devget->soft_count = 1487*30391Skarels sc->sc_softcnt; /* soft er. cnt.*/ 1488*30391Skarels devget->hard_count = 1489*30391Skarels sc->sc_hardcnt; /* hard er cnt. */ 1490*30391Skarels devget->stat = sc->sc_flags; /* status */ 1491*30391Skarels devget->category_stat = 1492*30391Skarels sc->sc_category_flags; /* cat. stat. */ 1493*30391Skarels break; 1494*30391Skarels 1495*30391Skarels default: 1496*30391Skarels /*----------------------------- 1497*30391Skarels * service tty type ioctl's */ 1498*30391Skarels 1499*30391Skarels if (!(minor_dev & 0x02)) { 1500*30391Skarels 1501*30391Skarels tp = &qd_tty[minor_dev]; 1502*30391Skarels 1503*30391Skarels error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); 1504*30391Skarels if (error >= 0) { 1505*30391Skarels return(error); 1506*30391Skarels } 1507*30391Skarels 1508*30391Skarels error = ttioctl(tp, cmd, datap, flags); 1509*30391Skarels if (error >= 0) { 1510*30391Skarels return(error); 1511*30391Skarels } 1512*30391Skarels } 1513*30391Skarels break; 1514*30391Skarels } 1515*30391Skarels 1516*30391Skarels /*-------------------------------- 1517*30391Skarels * clean up and get outta here */ 1518*30391Skarels 1519*30391Skarels return(0); 1520*30391Skarels 1521*30391Skarels } /* qdioctl */ 1522*30391Skarels 1523*30391Skarels /********************************************************************** 1524*30391Skarels * 1525*30391Skarels * qdselect()... service select call for event queue input 1526*30391Skarels * 1527*30391Skarels **********************************************************************/ 1528*30391Skarels 1529*30391Skarels qdselect(dev, rw) 1530*30391Skarels dev_t dev; 1531*30391Skarels int rw; 1532*30391Skarels { 1533*30391Skarels register int s; 1534*30391Skarels register int unit; 1535*30391Skarels 1536*30391Skarels s = spl5(); 1537*30391Skarels unit = minor(dev) >> 2; 1538*30391Skarels 1539*30391Skarels switch (rw) { 1540*30391Skarels 1541*30391Skarels case FREAD: /* event available? */ 1542*30391Skarels 1543*30391Skarels if(!(ISEMPTY(eq_header[unit]))) { 1544*30391Skarels splx(s); 1545*30391Skarels return(1); /* return "1" if event exists */ 1546*30391Skarels } 1547*30391Skarels rsel[unit] = u.u_procp; 1548*30391Skarels qdflags[unit].selmask |= SEL_READ; 1549*30391Skarels splx(s); 1550*30391Skarels return(0); 1551*30391Skarels 1552*30391Skarels case FWRITE: /* DMA done? */ 1553*30391Skarels 1554*30391Skarels if (DMA_ISEMPTY(DMAheader[unit])) { 1555*30391Skarels splx(s); 1556*30391Skarels return(1); /* return "1" if DMA is done */ 1557*30391Skarels } 1558*30391Skarels rsel[unit] = u.u_procp; 1559*30391Skarels qdflags[unit].selmask |= SEL_WRITE; 1560*30391Skarels splx(s); 1561*30391Skarels return(0); 1562*30391Skarels } 1563*30391Skarels 1564*30391Skarels } /* qdselect() */ 1565*30391Skarels 1566*30391Skarels /*************************************************************** 1567*30391Skarels * 1568*30391Skarels * qdwrite()... output to the QDSS screen as a TTY 1569*30391Skarels * 1570*30391Skarels ***************************************************************/ 1571*30391Skarels 1572*30391Skarels extern qd_strategy(); 1573*30391Skarels 1574*30391Skarels qdwrite(dev, uio) 1575*30391Skarels dev_t dev; 1576*30391Skarels struct uio *uio; 1577*30391Skarels { 1578*30391Skarels register struct tty *tp; 1579*30391Skarels register int minor_dev; 1580*30391Skarels register int unit; 1581*30391Skarels 1582*30391Skarels minor_dev = minor(dev); 1583*30391Skarels unit = (minor_dev >> 2) & 0x07; 1584*30391Skarels 1585*30391Skarels /*------------------------------ 1586*30391Skarels * if this is the console... */ 1587*30391Skarels 1588*30391Skarels if ((minor_dev & 0x03) != 0x02 && 1589*30391Skarels qdflags[unit].inuse & CONS_DEV) { 1590*30391Skarels tp = &qd_tty[minor_dev]; 1591*30391Skarels return ((*linesw[tp->t_line].l_write)(tp, uio)); 1592*30391Skarels } 1593*30391Skarels 1594*30391Skarels /*------------------------------------------------ 1595*30391Skarels * else this must be a DMA xfer from user space */ 1596*30391Skarels 1597*30391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 1598*30391Skarels return (physio(qd_strategy, &qdbuf[unit], 1599*30391Skarels dev, B_WRITE, minphys, uio)); 1600*30391Skarels } 1601*30391Skarels } 1602*30391Skarels 1603*30391Skarels /*************************************************************** 1604*30391Skarels * 1605*30391Skarels * qdread()... read from QDSS keyboard as a TTY 1606*30391Skarels * 1607*30391Skarels ***************************************************************/ 1608*30391Skarels 1609*30391Skarels qdread(dev, uio) 1610*30391Skarels dev_t dev; 1611*30391Skarels struct uio *uio; 1612*30391Skarels { 1613*30391Skarels register struct tty *tp; 1614*30391Skarels register int minor_dev; 1615*30391Skarels register int unit; 1616*30391Skarels 1617*30391Skarels minor_dev = minor(dev); 1618*30391Skarels unit = (minor_dev >> 2) & 0x07; 1619*30391Skarels 1620*30391Skarels /*------------------------------ 1621*30391Skarels * if this is the console... */ 1622*30391Skarels 1623*30391Skarels if ((minor_dev & 0x03) != 0x02 && 1624*30391Skarels qdflags[unit].inuse & CONS_DEV) { 1625*30391Skarels tp = &qd_tty[minor_dev]; 1626*30391Skarels return ((*linesw[tp->t_line].l_read)(tp, uio)); 1627*30391Skarels } 1628*30391Skarels 1629*30391Skarels /*------------------------------------------------ 1630*30391Skarels * else this must be a bitmap-to-processor xfer */ 1631*30391Skarels 1632*30391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 1633*30391Skarels return (physio(qd_strategy, &qdbuf[unit], 1634*30391Skarels dev, B_READ, minphys, uio)); 1635*30391Skarels } 1636*30391Skarels } 1637*30391Skarels 1638*30391Skarels /*************************************************************** 1639*30391Skarels * 1640*30391Skarels * qd_strategy()... strategy routine to do DMA 1641*30391Skarels * 1642*30391Skarels ***************************************************************/ 1643*30391Skarels 1644*30391Skarels qd_strategy(bp) 1645*30391Skarels register struct buf *bp; 1646*30391Skarels { 1647*30391Skarels register struct dga *dga; 1648*30391Skarels register struct adder *adder; 1649*30391Skarels 1650*30391Skarels char *DMAbufp; 1651*30391Skarels 1652*30391Skarels int QBAreg; 1653*30391Skarels int bytcnt; 1654*30391Skarels int s; 1655*30391Skarels int unit; 1656*30391Skarels int cookie; 1657*30391Skarels 1658*30391Skarels int i,j,k; 1659*30391Skarels 1660*30391Skarels unit = (minor(bp->b_dev) >> 2) & 0x07; 1661*30391Skarels 1662*30391Skarels /*----------------- 1663*30391Skarels * init pointers */ 1664*30391Skarels 1665*30391Skarels if ((QBAreg = ubasetup(0, bp, 0)) == 0) { 1666*30391Skarels mprintf("\nqd%d: qd_strategy: QBA setup error", unit); 1667*30391Skarels goto STRAT_ERR; 1668*30391Skarels } 1669*30391Skarels 1670*30391Skarels dga = (struct dga *) qdmap[unit].dga; 1671*30391Skarels 1672*30391Skarels s = spl5(); 1673*30391Skarels 1674*30391Skarels qdflags[unit].user_dma = -1; 1675*30391Skarels 1676*30391Skarels dga->csr |= DMA_IE; 1677*30391Skarels 1678*30391Skarels cookie = QBAreg & 0x3FFFF; 1679*30391Skarels dga->adrs_lo = (short) cookie; 1680*30391Skarels dga->adrs_hi = (short) (cookie >> 16); 1681*30391Skarels 1682*30391Skarels dga->bytcnt_lo = (short) bp->b_bcount; 1683*30391Skarels dga->bytcnt_hi = (short) (bp->b_bcount >> 16); 1684*30391Skarels 1685*30391Skarels while (qdflags[unit].user_dma) { 1686*30391Skarels sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); 1687*30391Skarels } 1688*30391Skarels 1689*30391Skarels splx(s); 1690*30391Skarels ubarelse(0, &QBAreg); 1691*30391Skarels 1692*30391Skarels if (!(dga->csr & DMA_ERR)) { 1693*30391Skarels iodone(bp); 1694*30391Skarels return; 1695*30391Skarels } 1696*30391Skarels 1697*30391Skarels STRAT_ERR: 1698*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1699*30391Skarels adder->command = CANCEL; /* cancel adder activity */ 1700*30391Skarels dga->csr &= ~DMA_IE; 1701*30391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 1702*30391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 1703*30391Skarels bp->b_flags |= B_ERROR; /* flag an error to physio() */ 1704*30391Skarels 1705*30391Skarels /* if DMA was running, flush spurious intrpt */ 1706*30391Skarels 1707*30391Skarels if (dga->bytcnt_lo != 0) { 1708*30391Skarels dga->bytcnt_lo = 0; 1709*30391Skarels dga->bytcnt_hi = 0; 1710*30391Skarels DMA_SETIGNORE(DMAheader[unit]); 1711*30391Skarels dga->csr |= DMA_IE; 1712*30391Skarels } 1713*30391Skarels 1714*30391Skarels iodone(bp); 1715*30391Skarels 1716*30391Skarels } /* qd_strategy */ 1717*30391Skarels 1718*30391Skarels /******************************************************************* 1719*30391Skarels * 1720*30391Skarels * qdstart()... startup output to the console screen 1721*30391Skarels * 1722*30391Skarels ******************************************************************** 1723*30391Skarels * 1724*30391Skarels * calling convention: 1725*30391Skarels * 1726*30391Skarels * qdstart(tp); 1727*30391Skarels * struct tty *tp; ;pointer to tty structure 1728*30391Skarels * 1729*30391Skarels ********/ 1730*30391Skarels 1731*30391Skarels qdstart(tp) 1732*30391Skarels register struct tty *tp; 1733*30391Skarels { 1734*30391Skarels register int which_unit, unit, c; 1735*30391Skarels register struct tty *tp0; 1736*30391Skarels int s; 1737*30391Skarels 1738*30391Skarels int curs_on; 1739*30391Skarels struct dga *dga; 1740*30391Skarels 1741*30391Skarels unit = minor(tp->t_dev); 1742*30391Skarels 1743*30391Skarels tp0 = &qd_tty[(unit & 0x0FC)+1]; 1744*30391Skarels which_unit = (unit >> 2) & 0x3; 1745*30391Skarels unit &= 0x03; 1746*30391Skarels 1747*30391Skarels s = spl5(); 1748*30391Skarels 1749*30391Skarels /*------------------------------------------------------------------ 1750*30391Skarels * If it's currently active, or delaying, no need to do anything. */ 1751*30391Skarels 1752*30391Skarels if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 1753*30391Skarels goto out; 1754*30391Skarels 1755*30391Skarels /*------------------------------------------------------------------- 1756*30391Skarels * Display chars until the queue is empty, if the alternate console device 1757*30391Skarels * is open direct chars there. Drop input from anything but the console 1758*30391Skarels * device on the floor. */ 1759*30391Skarels 1760*30391Skarels while (tp->t_outq.c_cc) { 1761*30391Skarels c = getc(&tp->t_outq); 1762*30391Skarels if (unit == 0) { 1763*30391Skarels if (tp0->t_state & TS_ISOPEN) 1764*30391Skarels (*linesw[tp0->t_line].l_rint)(c, tp0); 1765*30391Skarels else 1766*30391Skarels blitc(which_unit, c & 0xFF); 1767*30391Skarels } 1768*30391Skarels } 1769*30391Skarels 1770*30391Skarels /*-------------------------------------------------------- 1771*30391Skarels * If there are sleepers, and output has drained below low 1772*30391Skarels * water mark, wake up the sleepers. */ 1773*30391Skarels 1774*30391Skarels if ( tp->t_outq.c_cc <= TTLOWAT(tp) ) { 1775*30391Skarels if (tp->t_state & TS_ASLEEP){ 1776*30391Skarels tp->t_state &= ~TS_ASLEEP; 1777*30391Skarels wakeup((caddr_t) &tp->t_outq); 1778*30391Skarels } 1779*30391Skarels } 1780*30391Skarels 1781*30391Skarels tp->t_state &= ~TS_BUSY; 1782*30391Skarels 1783*30391Skarels out: 1784*30391Skarels splx(s); 1785*30391Skarels 1786*30391Skarels } /* qdstart */ 1787*30391Skarels 1788*30391Skarels 1789*30391Skarels /******************************************************************* 1790*30391Skarels * 1791*30391Skarels * qdstop()... stop the tty 1792*30391Skarels * 1793*30391Skarels *******************************************************************/ 1794*30391Skarels 1795*30391Skarels qdstop(tp, flag) 1796*30391Skarels register struct tty *tp; 1797*30391Skarels int flag; 1798*30391Skarels { 1799*30391Skarels register int s; 1800*30391Skarels 1801*30391Skarels s = spl5(); /* block intrpts during state modification */ 1802*30391Skarels 1803*30391Skarels if (tp->t_state & TS_BUSY) { 1804*30391Skarels if ((tp->t_state & TS_TTSTOP) == 0) { 1805*30391Skarels tp->t_state |= TS_FLUSH; 1806*30391Skarels } else 1807*30391Skarels tp->t_state &= ~TS_BUSY; 1808*30391Skarels } 1809*30391Skarels splx(s); 1810*30391Skarels } 1811*30391Skarels 1812*30391Skarels /******************************************************************* 1813*30391Skarels * 1814*30391Skarels * blitc()... output a character to the QDSS screen 1815*30391Skarels * 1816*30391Skarels ******************************************************************** 1817*30391Skarels * 1818*30391Skarels * calling convention: 1819*30391Skarels * 1820*30391Skarels * blitc(chr); 1821*30391Skarels * char chr; ;character to be displayed 1822*30391Skarels * 1823*30391Skarels ********/ 1824*30391Skarels 1825*30391Skarels blitc(unit, chr) 1826*30391Skarels int unit; 1827*30391Skarels char chr; 1828*30391Skarels { 1829*30391Skarels register struct adder *adder; 1830*30391Skarels register struct dga *dga; 1831*30391Skarels register int i; 1832*30391Skarels 1833*30391Skarels short x; 1834*30391Skarels 1835*30391Skarels /*--------------- 1836*30391Skarels * init stuff */ 1837*30391Skarels 1838*30391Skarels adder = (struct adder *) qdmap[unit].adder; 1839*30391Skarels dga = (struct dga *) qdmap[unit].dga; 1840*30391Skarels 1841*30391Skarels /*--------------------------- 1842*30391Skarels * non display character? */ 1843*30391Skarels 1844*30391Skarels chr &= 0x7F; 1845*30391Skarels 1846*30391Skarels switch (chr) { 1847*30391Skarels 1848*30391Skarels case '\r': /* return char */ 1849*30391Skarels cursor[unit].x = 0; 1850*30391Skarels dga->x_cursor = TRANX(cursor[unit].x); 1851*30391Skarels return(0); 1852*30391Skarels 1853*30391Skarels case '\t': /* tab char */ 1854*30391Skarels 1855*30391Skarels for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) { 1856*30391Skarels blitc(unit, ' '); 1857*30391Skarels } 1858*30391Skarels return(0); 1859*30391Skarels 1860*30391Skarels case '\n': /* line feed char */ 1861*30391Skarels 1862*30391Skarels if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { 1863*30391Skarels if (qdflags[unit].inuse & GRAPHIC_DEV) { 1864*30391Skarels cursor[unit].y = 0; 1865*30391Skarels } else { 1866*30391Skarels cursor[unit].y -= CHAR_HEIGHT; 1867*30391Skarels scroll_up(adder); 1868*30391Skarels } 1869*30391Skarels } 1870*30391Skarels dga->y_cursor = TRANY(cursor[unit].y); 1871*30391Skarels return(0); 1872*30391Skarels 1873*30391Skarels case '\b': /* backspace char */ 1874*30391Skarels if (cursor[unit].x > 0) { 1875*30391Skarels cursor[unit].x -= CHAR_WIDTH; 1876*30391Skarels blitc(unit, ' '); 1877*30391Skarels cursor[unit].x -= CHAR_WIDTH; 1878*30391Skarels dga->x_cursor = TRANX(cursor[unit].x); 1879*30391Skarels } 1880*30391Skarels return(0); 1881*30391Skarels 1882*30391Skarels default: 1883*30391Skarels if (chr < ' ' || chr > '~') 1884*30391Skarels return(0); 1885*30391Skarels } 1886*30391Skarels 1887*30391Skarels /*------------------------------------------ 1888*30391Skarels * setup VIPER operand control registers */ 1889*30391Skarels 1890*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ 1891*30391Skarels write_ID(adder, SRC1_OCR_B, 1892*30391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 1893*30391Skarels 1894*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ 1895*30391Skarels write_ID(adder, SRC1_OCR_B, 1896*30391Skarels EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); 1897*30391Skarels 1898*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 1899*30391Skarels write_ID(adder, DST_OCR_B, 1900*30391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 1901*30391Skarels 1902*30391Skarels write_ID(adder, MASK_1, 0xFFFF); 1903*30391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); 1904*30391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 1905*30391Skarels 1906*30391Skarels /*---------------------------------------- 1907*30391Skarels * load DESTINATION origin and vectors */ 1908*30391Skarels 1909*30391Skarels adder->fast_dest_dy = 0; 1910*30391Skarels adder->slow_dest_dx = 0; 1911*30391Skarels adder->error_1 = 0; 1912*30391Skarels adder->error_2 = 0; 1913*30391Skarels 1914*30391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 1915*30391Skarels 1916*30391Skarels wait_status(adder, RASTEROP_COMPLETE); 1917*30391Skarels 1918*30391Skarels adder->destination_x = cursor[unit].x; 1919*30391Skarels adder->fast_dest_dx = CHAR_WIDTH; 1920*30391Skarels 1921*30391Skarels adder->destination_y = cursor[unit].y; 1922*30391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 1923*30391Skarels 1924*30391Skarels /*----------------------------------- 1925*30391Skarels * load SOURCE origin and vectors */ 1926*30391Skarels 1927*30391Skarels adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH); 1928*30391Skarels adder->source_1_y = FONT_Y; 1929*30391Skarels 1930*30391Skarels adder->source_1_dx = CHAR_WIDTH; 1931*30391Skarels adder->source_1_dy = CHAR_HEIGHT; 1932*30391Skarels 1933*30391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 1934*30391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 1935*30391Skarels 1936*30391Skarels /*------------------------------------- 1937*30391Skarels * update console cursor coordinates */ 1938*30391Skarels 1939*30391Skarels cursor[unit].x += CHAR_WIDTH; 1940*30391Skarels dga->x_cursor = TRANX(cursor[unit].x); 1941*30391Skarels 1942*30391Skarels if (cursor[unit].x > (1024 - CHAR_WIDTH)) { 1943*30391Skarels blitc(unit, '\r'); 1944*30391Skarels blitc(unit, '\n'); 1945*30391Skarels } 1946*30391Skarels 1947*30391Skarels } /* blitc */ 1948*30391Skarels 1949*30391Skarels qdreset(){} 1950*30391Skarels qd_init(){} 1951*30391Skarels 1952*30391Skarels /****************************************************************** 1953*30391Skarels ******************************************************************* 1954*30391Skarels ******************************************************************* 1955*30391Skarels * 1956*30391Skarels * INTERRUPT SERVICE ROUTINES START HERE: 1957*30391Skarels * 1958*30391Skarels ******************************************************************* 1959*30391Skarels ******************************************************************* 1960*30391Skarels ******************************************************************/ 1961*30391Skarels 1962*30391Skarels /***************************************************************** 1963*30391Skarels * 1964*30391Skarels * qddint()... service "DMA DONE" interrupt condition 1965*30391Skarels * 1966*30391Skarels *****************************************************************/ 1967*30391Skarels 1968*30391Skarels qddint(qd) 1969*30391Skarels int qd; 1970*30391Skarels { 1971*30391Skarels register struct DMAreq_header *header; 1972*30391Skarels register struct DMAreq *request; 1973*30391Skarels register struct dga *dga; 1974*30391Skarels struct adder *adder; 1975*30391Skarels 1976*30391Skarels int cookie; /* DMA adrs for QDSS */ 1977*30391Skarels int i; 1978*30391Skarels 1979*30391Skarels spl4(); /* allow interval timer in */ 1980*30391Skarels 1981*30391Skarels /*----------------- 1982*30391Skarels * init pointers */ 1983*30391Skarels 1984*30391Skarels header = DMAheader[qd]; /* register for optimization */ 1985*30391Skarels dga = (struct dga *) qdmap[qd].dga; 1986*30391Skarels adder = (struct adder *) qdmap[qd].adder; 1987*30391Skarels 1988*30391Skarels /*------------------------------------------------------------------------ 1989*30391Skarels * if this interrupt flagged as bogus for interrupt flushing purposes.. */ 1990*30391Skarels 1991*30391Skarels if (DMA_ISIGNORE(header)) { 1992*30391Skarels DMA_CLRIGNORE(header); 1993*30391Skarels return; 1994*30391Skarels } 1995*30391Skarels 1996*30391Skarels /*---------------------------------------------------- 1997*30391Skarels * dump a DMA hardware error message if appropriate */ 1998*30391Skarels 1999*30391Skarels if (dga->csr & DMA_ERR) { 2000*30391Skarels 2001*30391Skarels if (dga->csr & PARITY_ERR) 2002*30391Skarels mprintf("\nqd%d: qddint: DMA hardware parity fault.", qd); 2003*30391Skarels 2004*30391Skarels if (dga->csr & BUS_ERR) 2005*30391Skarels mprintf("\nqd%d: qddint: DMA hardware bus error.", qd); 2006*30391Skarels } 2007*30391Skarels 2008*30391Skarels /*---------------------------------------- 2009*30391Skarels * if this was a DMA from user space... */ 2010*30391Skarels 2011*30391Skarels if (qdflags[qd].user_dma) { 2012*30391Skarels qdflags[qd].user_dma = 0; 2013*30391Skarels wakeup((caddr_t)&qdflags[qd].user_dma); 2014*30391Skarels return; 2015*30391Skarels } 2016*30391Skarels 2017*30391Skarels /*------------------------------------------------------------------------ 2018*30391Skarels * if we're doing DMA request queue services, field the error condition */ 2019*30391Skarels 2020*30391Skarels if (dga->csr & DMA_ERR) { 2021*30391Skarels 2022*30391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 2023*30391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 2024*30391Skarels adder->command = CANCEL; /* cancel adder activity */ 2025*30391Skarels 2026*30391Skarels DMA_SETERROR(header); /* flag error in header status word */ 2027*30391Skarels DMA_CLRACTIVE(header); 2028*30391Skarels header->DMAreq[header->oldest].DMAdone |= HARD_ERROR; 2029*30391Skarels header->newest = header->oldest; 2030*30391Skarels header->used = 0; 2031*30391Skarels 2032*30391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 2033*30391Skarels selwakeup(rsel[qd], 0); 2034*30391Skarels rsel[qd] = 0; 2035*30391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 2036*30391Skarels } 2037*30391Skarels 2038*30391Skarels if (dga->bytcnt_lo != 0) { 2039*30391Skarels dga->bytcnt_lo = 0; 2040*30391Skarels dga->bytcnt_hi = 0; 2041*30391Skarels DMA_SETIGNORE(header); 2042*30391Skarels } 2043*30391Skarels 2044*30391Skarels return; 2045*30391Skarels } 2046*30391Skarels 2047*30391Skarels /*---------------------------------------------------------------------------- 2048*30391Skarels * if the DMA request queue is now becoming non-full, wakeup "select" client */ 2049*30391Skarels 2050*30391Skarels if (DMA_ISFULL(header)) { 2051*30391Skarels 2052*30391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 2053*30391Skarels selwakeup(rsel[qd], 0); 2054*30391Skarels rsel[qd] = 0; 2055*30391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 2056*30391Skarels } 2057*30391Skarels } 2058*30391Skarels 2059*30391Skarels header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE; 2060*30391Skarels 2061*30391Skarels if (DMA_ISEMPTY(header)) { 2062*30391Skarels mprintf("\nqd%d: qddint: unexpected interrupt", qd); 2063*30391Skarels return; 2064*30391Skarels } 2065*30391Skarels 2066*30391Skarels DMA_GETEND(header); /* update request queue indices */ 2067*30391Skarels 2068*30391Skarels /*------------------------------------------------------------ 2069*30391Skarels * if no more DMA pending, wake up "select" client and exit */ 2070*30391Skarels 2071*30391Skarels if (DMA_ISEMPTY(header)) { 2072*30391Skarels 2073*30391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 2074*30391Skarels selwakeup(rsel[qd], 0); 2075*30391Skarels rsel[qd] = 0; 2076*30391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 2077*30391Skarels } 2078*30391Skarels 2079*30391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 2080*30391Skarels return; 2081*30391Skarels } 2082*30391Skarels 2083*30391Skarels /*--------------------------- 2084*30391Skarels * initiate next DMA xfer */ 2085*30391Skarels 2086*30391Skarels request = DMA_GETBEGIN(header); 2087*30391Skarels 2088*30391Skarels switch (request->DMAtype) { 2089*30391Skarels 2090*30391Skarels case DISPLIST: 2091*30391Skarels dga->csr |= DL_ENB; 2092*30391Skarels break; 2093*30391Skarels 2094*30391Skarels case PTOB: 2095*30391Skarels dga->csr |= PTOB_ENB; 2096*30391Skarels break; 2097*30391Skarels 2098*30391Skarels case BTOP: 2099*30391Skarels dga->csr |= BTOP_ENB; 2100*30391Skarels break; 2101*30391Skarels 2102*30391Skarels default: 2103*30391Skarels mprintf("\nqd%d: qddint: illegal DMAtype parameter.", qd); 2104*30391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 2105*30391Skarels return; 2106*30391Skarels } 2107*30391Skarels 2108*30391Skarels if (request->DMAdone & COUNT_ZERO) { 2109*30391Skarels dga->csr &= ~SET_DONE_FIFO; 2110*30391Skarels } else if (request->DMAdone & FIFO_EMPTY) { 2111*30391Skarels dga->csr |= SET_DONE_FIFO; 2112*30391Skarels } 2113*30391Skarels 2114*30391Skarels if (request->DMAdone & WORD_PACK) 2115*30391Skarels dga->csr &= ~BYTE_DMA; 2116*30391Skarels else if (request->DMAdone & BYTE_PACK) 2117*30391Skarels dga->csr |= BYTE_DMA; 2118*30391Skarels 2119*30391Skarels dga->csr |= DMA_IE; 2120*30391Skarels 2121*30391Skarels cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg; 2122*30391Skarels 2123*30391Skarels dga->adrs_lo = (short) cookie; 2124*30391Skarels dga->adrs_hi = (short) (cookie >> 16); 2125*30391Skarels 2126*30391Skarels dga->bytcnt_lo = (short) request->length; 2127*30391Skarels dga->bytcnt_hi = (short) (request->length >> 16); 2128*30391Skarels 2129*30391Skarels return; 2130*30391Skarels } 2131*30391Skarels 2132*30391Skarels /***************************************************************** 2133*30391Skarels * 2134*30391Skarels * qdaint()... ADDER interrupt service 2135*30391Skarels * 2136*30391Skarels *****************************************************************/ 2137*30391Skarels 2138*30391Skarels qdaint(qd) 2139*30391Skarels register int qd; 2140*30391Skarels { 2141*30391Skarels register struct adder *adder; 2142*30391Skarels struct color_buf *cbuf; 2143*30391Skarels 2144*30391Skarels short stat; 2145*30391Skarels int i; 2146*30391Skarels register struct rgb *rgbp; 2147*30391Skarels register short *red; 2148*30391Skarels register short *green; 2149*30391Skarels register short *blue; 2150*30391Skarels 2151*30391Skarels spl4(); /* allow interval timer in */ 2152*30391Skarels 2153*30391Skarels adder = (struct adder *) qdmap[qd].adder; 2154*30391Skarels 2155*30391Skarels /*------------------------------------------------------------------------ 2156*30391Skarels * service the vertical blank interrupt (VSYNC bit) by loading any pending 2157*30391Skarels * color map load request */ 2158*30391Skarels 2159*30391Skarels if (adder->status & VSYNC) { 2160*30391Skarels adder->status &= ~VSYNC; /* clear the interrupt */ 2161*30391Skarels 2162*30391Skarels cbuf = color_buf[qd]; 2163*30391Skarels if (cbuf->status & LOAD_COLOR_MAP) { 2164*30391Skarels 2165*30391Skarels red = (short *) qdmap[qd].red; 2166*30391Skarels green = (short *) qdmap[qd].green; 2167*30391Skarels blue = (short *) qdmap[qd].blue; 2168*30391Skarels 2169*30391Skarels for (i = cbuf->count, rgbp = cbuf->rgb; --i >= 0; rgbp++) { 2170*30391Skarels 2171*30391Skarels red[rgbp->offset] = (short) rgbp->red; 2172*30391Skarels green[rgbp->offset] = (short) rgbp->green; 2173*30391Skarels blue[rgbp->offset] = (short) rgbp->blue; 2174*30391Skarels } 2175*30391Skarels 2176*30391Skarels cbuf->status &= ~LOAD_COLOR_MAP; 2177*30391Skarels } 2178*30391Skarels } 2179*30391Skarels 2180*30391Skarels /*------------------------------------------------- 2181*30391Skarels * service the scroll interrupt (FRAME_SYNC bit) */ 2182*30391Skarels 2183*30391Skarels if (adder->status & FRAME_SYNC) { 2184*30391Skarels adder->status &= ~FRAME_SYNC; /* clear the interrupt */ 2185*30391Skarels 2186*30391Skarels if (scroll[qd]->status & LOAD_REGS) { 2187*30391Skarels 2188*30391Skarels for ( i = 1000, adder->status = 0 2189*30391Skarels ; i > 0 && !((stat = adder->status) & ID_SCROLL_READY) 2190*30391Skarels ; --i); 2191*30391Skarels 2192*30391Skarels if (i == 0) { 2193*30391Skarels mprintf("\nqd%d: qdaint: timeout on ID_SCROLL_READY", qd); 2194*30391Skarels return; 2195*30391Skarels } 2196*30391Skarels 2197*30391Skarels adder->ID_scroll_data = scroll[qd]->viper_constant; 2198*30391Skarels adder->ID_scroll_command = ID_LOAD | SCROLL_CONSTANT; 2199*30391Skarels 2200*30391Skarels adder->y_scroll_constant = scroll[qd]->y_scroll_constant; 2201*30391Skarels adder->y_offset_pending = scroll[qd]->y_offset; 2202*30391Skarels 2203*30391Skarels if (scroll[qd]->status & LOAD_INDEX) { 2204*30391Skarels 2205*30391Skarels adder->x_index_pending = scroll[qd]->x_index_pending; 2206*30391Skarels adder->y_index_pending = scroll[qd]->y_index_pending; 2207*30391Skarels } 2208*30391Skarels 2209*30391Skarels scroll[qd]->status = 0x00; 2210*30391Skarels } 2211*30391Skarels } 2212*30391Skarels } 2213*30391Skarels 2214*30391Skarels /***************************************************************** 2215*30391Skarels * 2216*30391Skarels * qdiint()... DUART input interrupt service routine 2217*30391Skarels * 2218*30391Skarels *****************************************************************/ 2219*30391Skarels 2220*30391Skarels qdiint(qd) 2221*30391Skarels register int qd; 2222*30391Skarels { 2223*30391Skarels register struct _vs_event *event; 2224*30391Skarels register struct qdinput *eqh; 2225*30391Skarels 2226*30391Skarels struct dga *dga; 2227*30391Skarels struct duart *duart; 2228*30391Skarels struct mouse_report *new_rep; 2229*30391Skarels 2230*30391Skarels struct uba_device *ui; 2231*30391Skarels struct tty *tp; 2232*30391Skarels 2233*30391Skarels char chr; 2234*30391Skarels int i,j; 2235*30391Skarels int k,l; 2236*30391Skarels 2237*30391Skarels u_short status; 2238*30391Skarels u_short data; 2239*30391Skarels u_short key; 2240*30391Skarels 2241*30391Skarels char do_wakeup = 0; /* flag to do a select wakeup call */ 2242*30391Skarels char a, b, c; /* mouse button test variables */ 2243*30391Skarels 2244*30391Skarels spl4(); /* allow interval timer in */ 2245*30391Skarels 2246*30391Skarels eqh = eq_header[qd]; /* optimized as a register */ 2247*30391Skarels new_rep = ¤t_rep[qd]; 2248*30391Skarels duart = (struct duart *) qdmap[qd].duart; 2249*30391Skarels 2250*30391Skarels /*----------------------------------------- 2251*30391Skarels * if the graphic device is turned on.. */ 2252*30391Skarels 2253*30391Skarels if (qdflags[qd].inuse & GRAPHIC_DEV) { 2254*30391Skarels 2255*30391Skarels /*--------------- 2256*30391Skarels * empty DUART */ 2257*30391Skarels 2258*30391Skarels while ((status = duart->statusA) & RCV_RDY || 2259*30391Skarels (status = duart->statusB) & RCV_RDY) { 2260*30391Skarels 2261*30391Skarels /*--------------------------------- 2262*30391Skarels * pick up LK-201 input (if any) */ 2263*30391Skarels 2264*30391Skarels if ((status = duart->statusA) & RCV_RDY) { 2265*30391Skarels 2266*30391Skarels /* if error condition, then reset it */ 2267*30391Skarels 2268*30391Skarels if ((status = duart->statusA) & 0x70) { 2269*30391Skarels duart->cmdA = 0x40; 2270*30391Skarels continue; 2271*30391Skarels } 2272*30391Skarels 2273*30391Skarels /* event queue full now? (overflow condition) */ 2274*30391Skarels 2275*30391Skarels if (ISFULL(eqh) == TRUE) { 2276*30391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 2277*30391Skarels break; 2278*30391Skarels } 2279*30391Skarels 2280*30391Skarels /*-------------------------------------- 2281*30391Skarels * Check for various keyboard errors */ 2282*30391Skarels 2283*30391Skarels key = duart->dataA & 0xFF; 2284*30391Skarels 2285*30391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 2286*30391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2287*30391Skarels mprintf("\nqd%d: qdiint: keyboard error, code = %x",qd,key); 2288*30391Skarels return(0); 2289*30391Skarels } 2290*30391Skarels 2291*30391Skarels if (key < LK_LOWEST) 2292*30391Skarels return(0); 2293*30391Skarels 2294*30391Skarels ++do_wakeup; /* request a select wakeup call */ 2295*30391Skarels 2296*30391Skarels event = PUTBEGIN(eqh); 2297*30391Skarels PUTEND(eqh); 2298*30391Skarels 2299*30391Skarels event->vse_key = key; 2300*30391Skarels event->vse_key &= 0x00FF; 2301*30391Skarels event->vse_x = eqh->curs_pos.x; 2302*30391Skarels event->vse_y = eqh->curs_pos.y; 2303*30391Skarels event->vse_time = TOY; 2304*30391Skarels event->vse_type = VSE_BUTTON; 2305*30391Skarels event->vse_direction = VSE_KBTRAW; 2306*30391Skarels event->vse_device = VSE_DKB; 2307*30391Skarels } 2308*30391Skarels 2309*30391Skarels /*------------------------------------- 2310*30391Skarels * pick up the mouse input (if any) */ 2311*30391Skarels 2312*30391Skarels if ((status = duart->statusB) & RCV_RDY && 2313*30391Skarels qdflags[qd].pntr_id == MOUSE_ID) { 2314*30391Skarels 2315*30391Skarels if (status & 0x70) { 2316*30391Skarels duart->cmdB = 0x40; 2317*30391Skarels continue; 2318*30391Skarels } 2319*30391Skarels 2320*30391Skarels /* event queue full now? (overflow condition) */ 2321*30391Skarels 2322*30391Skarels if (ISFULL(eqh) == TRUE) { 2323*30391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 2324*30391Skarels break; 2325*30391Skarels } 2326*30391Skarels 2327*30391Skarels data = duart->dataB; /* get report byte */ 2328*30391Skarels ++new_rep->bytcnt; /* bump report byte count */ 2329*30391Skarels 2330*30391Skarels /*--------------------------- 2331*30391Skarels * if 1st byte of report.. */ 2332*30391Skarels 2333*30391Skarels if ( data & START_FRAME) { 2334*30391Skarels new_rep->state = data; 2335*30391Skarels if (new_rep->bytcnt > 1) { 2336*30391Skarels new_rep->bytcnt = 1; /* start of new frame */ 2337*30391Skarels continue; /* ..continue looking */ 2338*30391Skarels } 2339*30391Skarels } 2340*30391Skarels 2341*30391Skarels /*--------------------------- 2342*30391Skarels * if 2nd byte of report.. */ 2343*30391Skarels 2344*30391Skarels else if (new_rep->bytcnt == 2) { 2345*30391Skarels new_rep->dx = data & 0x00FF; 2346*30391Skarels } 2347*30391Skarels 2348*30391Skarels /*------------------------------------------------- 2349*30391Skarels * if 3rd byte of report, load input event queue */ 2350*30391Skarels 2351*30391Skarels else if (new_rep->bytcnt == 3) { 2352*30391Skarels 2353*30391Skarels new_rep->dy = data & 0x00FF; 2354*30391Skarels new_rep->bytcnt = 0; 2355*30391Skarels 2356*30391Skarels /*----------------------------------- 2357*30391Skarels * if mouse position has changed.. */ 2358*30391Skarels 2359*30391Skarels if (new_rep->dx != 0 || new_rep->dy != 0) { 2360*30391Skarels 2361*30391Skarels /*--------------------------------------------- 2362*30391Skarels * calculate acceleration factor, if needed */ 2363*30391Skarels 2364*30391Skarels if (qdflags[qd].curs_acc > ACC_OFF) { 2365*30391Skarels 2366*30391Skarels if (qdflags[qd].curs_thr <= new_rep->dx) 2367*30391Skarels new_rep->dx += 2368*30391Skarels (new_rep->dx - qdflags[qd].curs_thr) 2369*30391Skarels * qdflags[qd].curs_acc; 2370*30391Skarels 2371*30391Skarels if (qdflags[qd].curs_thr <= new_rep->dy) 2372*30391Skarels new_rep->dy += 2373*30391Skarels (new_rep->dy - qdflags[qd].curs_thr) 2374*30391Skarels * qdflags[qd].curs_acc; 2375*30391Skarels } 2376*30391Skarels 2377*30391Skarels /*------------------------------------- 2378*30391Skarels * update cursor position coordinates */ 2379*30391Skarels 2380*30391Skarels if (new_rep->state & X_SIGN) { 2381*30391Skarels eqh->curs_pos.x += new_rep->dx; 2382*30391Skarels if (eqh->curs_pos.x > 1023) 2383*30391Skarels eqh->curs_pos.x = 1023; 2384*30391Skarels } 2385*30391Skarels else { 2386*30391Skarels eqh->curs_pos.x -= new_rep->dx; 2387*30391Skarels if (eqh->curs_pos.x < -15) 2388*30391Skarels eqh->curs_pos.x = -15; 2389*30391Skarels } 2390*30391Skarels 2391*30391Skarels if (new_rep->state & Y_SIGN) { 2392*30391Skarels eqh->curs_pos.y -= new_rep->dy; 2393*30391Skarels if (eqh->curs_pos.y < -15) 2394*30391Skarels eqh->curs_pos.y = -15; 2395*30391Skarels } 2396*30391Skarels else { 2397*30391Skarels eqh->curs_pos.y += new_rep->dy; 2398*30391Skarels if (eqh->curs_pos.y > 863) 2399*30391Skarels eqh->curs_pos.y = 863; 2400*30391Skarels } 2401*30391Skarels 2402*30391Skarels /*--------------------------------- 2403*30391Skarels * update cursor screen position */ 2404*30391Skarels 2405*30391Skarels dga = (struct dga *) qdmap[qd].dga; 2406*30391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 2407*30391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 2408*30391Skarels 2409*30391Skarels /*-------------------------------------------- 2410*30391Skarels * if cursor is in the box, no event report */ 2411*30391Skarels 2412*30391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 2413*30391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 2414*30391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 2415*30391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 2416*30391Skarels goto GET_MBUTTON; 2417*30391Skarels } 2418*30391Skarels 2419*30391Skarels /*--------------------------------- 2420*30391Skarels * report the mouse motion event */ 2421*30391Skarels 2422*30391Skarels event = PUTBEGIN(eqh); 2423*30391Skarels PUTEND(eqh); 2424*30391Skarels 2425*30391Skarels ++do_wakeup; /* request a select wakeup call */ 2426*30391Skarels 2427*30391Skarels event->vse_x = eqh->curs_pos.x; 2428*30391Skarels event->vse_y = eqh->curs_pos.y; 2429*30391Skarels 2430*30391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 2431*30391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 2432*30391Skarels event->vse_key = 0; 2433*30391Skarels event->vse_direction = 0; 2434*30391Skarels event->vse_time = TOY; /* time stamp */ 2435*30391Skarels } 2436*30391Skarels 2437*30391Skarels GET_MBUTTON: 2438*30391Skarels /*------------------------------- 2439*30391Skarels * if button state has changed */ 2440*30391Skarels 2441*30391Skarels a = new_rep->state & 0x07; /*mask nonbutton bits */ 2442*30391Skarels b = last_rep[qd].state & 0x07; 2443*30391Skarels 2444*30391Skarels if (a ^ b) { 2445*30391Skarels 2446*30391Skarels for ( c = 1; c < 8; c <<= 1) { 2447*30391Skarels 2448*30391Skarels if (!( c & (a ^ b))) /* this button change? */ 2449*30391Skarels continue; 2450*30391Skarels 2451*30391Skarels /* event queue full? (overflow condition) */ 2452*30391Skarels 2453*30391Skarels if (ISFULL(eqh) == TRUE) { 2454*30391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 2455*30391Skarels break; 2456*30391Skarels } 2457*30391Skarels 2458*30391Skarels event = PUTBEGIN(eqh); /* get new event */ 2459*30391Skarels PUTEND(eqh); 2460*30391Skarels 2461*30391Skarels ++do_wakeup; /* request select wakeup */ 2462*30391Skarels 2463*30391Skarels event->vse_x = eqh->curs_pos.x; 2464*30391Skarels event->vse_y = eqh->curs_pos.y; 2465*30391Skarels 2466*30391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 2467*30391Skarels event->vse_type = VSE_BUTTON; /* new button */ 2468*30391Skarels event->vse_time = TOY; /* time stamp */ 2469*30391Skarels 2470*30391Skarels /* flag changed button and if up or down */ 2471*30391Skarels 2472*30391Skarels if (c == RIGHT_BUTTON) 2473*30391Skarels event->vse_key = VSE_RIGHT_BUTTON; 2474*30391Skarels else if (c == MIDDLE_BUTTON) 2475*30391Skarels event->vse_key = VSE_MIDDLE_BUTTON; 2476*30391Skarels else if (c == LEFT_BUTTON) 2477*30391Skarels event->vse_key = VSE_LEFT_BUTTON; 2478*30391Skarels 2479*30391Skarels /* set bit = button depressed */ 2480*30391Skarels 2481*30391Skarels if (c & a) 2482*30391Skarels event->vse_direction = VSE_KBTDOWN; 2483*30391Skarels else 2484*30391Skarels event->vse_direction = VSE_KBTUP; 2485*30391Skarels } 2486*30391Skarels } 2487*30391Skarels 2488*30391Skarels /* refresh last report */ 2489*30391Skarels 2490*30391Skarels last_rep[qd] = current_rep[qd]; 2491*30391Skarels 2492*30391Skarels } /* get last byte of report */ 2493*30391Skarels } /* pickup mouse input */ 2494*30391Skarels 2495*30391Skarels /*-------------------------------- 2496*30391Skarels * pickup tablet input, if any */ 2497*30391Skarels 2498*30391Skarels else if ((status = duart->statusB) & RCV_RDY && 2499*30391Skarels qdflags[qd].pntr_id == TABLET_ID) { 2500*30391Skarels 2501*30391Skarels if (status & 0x70) { 2502*30391Skarels duart->cmdB = 0x40; 2503*30391Skarels continue; 2504*30391Skarels } 2505*30391Skarels 2506*30391Skarels /* event queue full now? (overflow condition) */ 2507*30391Skarels 2508*30391Skarels if (ISFULL(eqh) == TRUE) { 2509*30391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 2510*30391Skarels break; 2511*30391Skarels } 2512*30391Skarels 2513*30391Skarels data = duart->dataB; /* get report byte */ 2514*30391Skarels ++new_rep->bytcnt; /* bump report byte count */ 2515*30391Skarels 2516*30391Skarels /*--------------------------- 2517*30391Skarels * if 1st byte of report.. */ 2518*30391Skarels 2519*30391Skarels if (data & START_FRAME) { 2520*30391Skarels new_rep->state = data; 2521*30391Skarels if (new_rep->bytcnt > 1) { 2522*30391Skarels new_rep->bytcnt = 1; /* start of new frame */ 2523*30391Skarels continue; /* ..continue looking */ 2524*30391Skarels } 2525*30391Skarels } 2526*30391Skarels 2527*30391Skarels /*--------------------------- 2528*30391Skarels * if 2nd byte of report.. */ 2529*30391Skarels 2530*30391Skarels else if (new_rep->bytcnt == 2) { 2531*30391Skarels new_rep->dx = data & 0x3F; 2532*30391Skarels } 2533*30391Skarels 2534*30391Skarels /*--------------------------- 2535*30391Skarels * if 3rd byte of report.. */ 2536*30391Skarels 2537*30391Skarels else if (new_rep->bytcnt == 3) { 2538*30391Skarels new_rep->dx |= (data & 0x3F) << 6; 2539*30391Skarels } 2540*30391Skarels 2541*30391Skarels /*--------------------------- 2542*30391Skarels * if 4th byte of report.. */ 2543*30391Skarels 2544*30391Skarels else if (new_rep->bytcnt == 4) { 2545*30391Skarels new_rep->dy = data & 0x3F; 2546*30391Skarels } 2547*30391Skarels 2548*30391Skarels /*------------------------------------------------- 2549*30391Skarels * if 5th byte of report, load input event queue */ 2550*30391Skarels 2551*30391Skarels else if (new_rep->bytcnt == 5) { 2552*30391Skarels 2553*30391Skarels new_rep->dy |= (data & 0x3F) << 6; 2554*30391Skarels new_rep->bytcnt = 0; 2555*30391Skarels 2556*30391Skarels /*------------------------------------- 2557*30391Skarels * update cursor position coordinates */ 2558*30391Skarels 2559*30391Skarels new_rep->dx /= qdflags[qd].tab_res; 2560*30391Skarels new_rep->dy = (2200 - new_rep->dy) 2561*30391Skarels / qdflags[qd].tab_res; 2562*30391Skarels 2563*30391Skarels if (new_rep->dx > 1023) { 2564*30391Skarels new_rep->dx = 1023; 2565*30391Skarels } 2566*30391Skarels if (new_rep->dy > 863) { 2567*30391Skarels new_rep->dy = 863; 2568*30391Skarels } 2569*30391Skarels 2570*30391Skarels /* 2571*30391Skarels * report an event if the puck/stylus has moved 2572*30391Skarels */ 2573*30391Skarels 2574*30391Skarels if (eqh->curs_pos.x != new_rep->dx || 2575*30391Skarels eqh->curs_pos.y != new_rep->dy) { 2576*30391Skarels 2577*30391Skarels eqh->curs_pos.x = new_rep->dx; 2578*30391Skarels eqh->curs_pos.y = new_rep->dy; 2579*30391Skarels 2580*30391Skarels /*--------------------------------- 2581*30391Skarels * update cursor screen position */ 2582*30391Skarels 2583*30391Skarels dga = (struct dga *) qdmap[qd].dga; 2584*30391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 2585*30391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 2586*30391Skarels 2587*30391Skarels /* 2588*30391Skarels * if cursor is in the box, no event report 2589*30391Skarels */ 2590*30391Skarels 2591*30391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 2592*30391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 2593*30391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 2594*30391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 2595*30391Skarels goto GET_TBUTTON; 2596*30391Skarels } 2597*30391Skarels 2598*30391Skarels /*--------------------------------- 2599*30391Skarels * report the tablet motion event */ 2600*30391Skarels 2601*30391Skarels event = PUTBEGIN(eqh); 2602*30391Skarels PUTEND(eqh); 2603*30391Skarels 2604*30391Skarels ++do_wakeup; /* request a select wakeup call */ 2605*30391Skarels 2606*30391Skarels event->vse_x = eqh->curs_pos.x; 2607*30391Skarels event->vse_y = eqh->curs_pos.y; 2608*30391Skarels 2609*30391Skarels event->vse_device = VSE_TABLET; /* tablet */ 2610*30391Skarels /* 2611*30391Skarels * right now, X handles tablet motion the same 2612*30391Skarels * as mouse motion 2613*30391Skarels */ 2614*30391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 2615*30391Skarels event->vse_key = 0; 2616*30391Skarels event->vse_direction = 0; 2617*30391Skarels event->vse_time = TOY; /* time stamp */ 2618*30391Skarels } 2619*30391Skarels GET_TBUTTON: 2620*30391Skarels /*------------------------------- 2621*30391Skarels * if button state has changed */ 2622*30391Skarels 2623*30391Skarels a = new_rep->state & 0x1E; /* mask nonbutton bits */ 2624*30391Skarels b = last_rep[qd].state & 0x1E; 2625*30391Skarels 2626*30391Skarels if (a ^ b) { 2627*30391Skarels 2628*30391Skarels /* event queue full now? (overflow condition) */ 2629*30391Skarels 2630*30391Skarels if (ISFULL(eqh) == TRUE) { 2631*30391Skarels mprintf("\nqd%d: qdiint: event queue overflow",qd); 2632*30391Skarels break; 2633*30391Skarels } 2634*30391Skarels 2635*30391Skarels event = PUTBEGIN(eqh); /* get new event */ 2636*30391Skarels PUTEND(eqh); 2637*30391Skarels 2638*30391Skarels ++do_wakeup; /* request a select wakeup call */ 2639*30391Skarels 2640*30391Skarels event->vse_x = eqh->curs_pos.x; 2641*30391Skarels event->vse_y = eqh->curs_pos.y; 2642*30391Skarels 2643*30391Skarels event->vse_device = VSE_TABLET; /* tablet */ 2644*30391Skarels event->vse_type = VSE_BUTTON; /* button changed */ 2645*30391Skarels event->vse_time = TOY; /* time stamp */ 2646*30391Skarels 2647*30391Skarels /* define the changed button and if up or down */ 2648*30391Skarels 2649*30391Skarels for ( c = 1; c <= 0x10; c <<= 1) { 2650*30391Skarels if (c & (a ^ b)) { 2651*30391Skarels if (c == T_LEFT_BUTTON) 2652*30391Skarels event->vse_key = VSE_T_LEFT_BUTTON; 2653*30391Skarels else if (c == T_FRONT_BUTTON) 2654*30391Skarels event->vse_key = VSE_T_FRONT_BUTTON; 2655*30391Skarels else if (c == T_RIGHT_BUTTON) 2656*30391Skarels event->vse_key = VSE_T_RIGHT_BUTTON; 2657*30391Skarels else if (c == T_BACK_BUTTON) 2658*30391Skarels event->vse_key = VSE_T_BACK_BUTTON; 2659*30391Skarels break; 2660*30391Skarels } 2661*30391Skarels } 2662*30391Skarels 2663*30391Skarels /* set bit = button depressed */ 2664*30391Skarels 2665*30391Skarels if (c & a) 2666*30391Skarels event->vse_direction = VSE_KBTDOWN; 2667*30391Skarels else 2668*30391Skarels event->vse_direction = VSE_KBTUP; 2669*30391Skarels } 2670*30391Skarels 2671*30391Skarels /* refresh last report */ 2672*30391Skarels 2673*30391Skarels last_rep[qd] = current_rep[qd]; 2674*30391Skarels 2675*30391Skarels } /* get last byte of report */ 2676*30391Skarels } /* pick up tablet input */ 2677*30391Skarels 2678*30391Skarels } /* while input available.. */ 2679*30391Skarels 2680*30391Skarels /*--------------------- 2681*30391Skarels * do select wakeup */ 2682*30391Skarels 2683*30391Skarels if (rsel[qd] && do_wakeup && qdflags[qd].selmask & SEL_READ) { 2684*30391Skarels selwakeup(rsel[qd], 0); 2685*30391Skarels rsel[qd] = 0; 2686*30391Skarels qdflags[qd].selmask &= ~SEL_READ; 2687*30391Skarels do_wakeup = 0; 2688*30391Skarels } 2689*30391Skarels } 2690*30391Skarels 2691*30391Skarels /*----------------------------------------------------------------- 2692*30391Skarels * if the graphic device is not turned on, this is console input */ 2693*30391Skarels 2694*30391Skarels else { 2695*30391Skarels 2696*30391Skarels ui = qdinfo[qd]; 2697*30391Skarels if (ui == 0 || ui->ui_alive == 0) 2698*30391Skarels return(0); 2699*30391Skarels 2700*30391Skarels tp = &qd_tty[qd << 2]; 2701*30391Skarels 2702*30391Skarels /*-------------------------------------- 2703*30391Skarels * Get a character from the keyboard. */ 2704*30391Skarels 2705*30391Skarels while ((status = duart->statusA) & RCV_RDY) { 2706*30391Skarels 2707*30391Skarels key = duart->dataA; 2708*30391Skarels key &= 0xFF; 2709*30391Skarels 2710*30391Skarels /*-------------------------------------- 2711*30391Skarels * Check for various keyboard errors */ 2712*30391Skarels 2713*30391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 2714*30391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2715*30391Skarels mprintf("\nqd%d: qdiint: Keyboard error, code = %x",qd,key); 2716*30391Skarels return(0); 2717*30391Skarels } 2718*30391Skarels 2719*30391Skarels if (key < LK_LOWEST) 2720*30391Skarels return(0); 2721*30391Skarels 2722*30391Skarels /*--------------------------------- 2723*30391Skarels * See if its a state change key */ 2724*30391Skarels 2725*30391Skarels switch (key) { 2726*30391Skarels 2727*30391Skarels case LOCK: 2728*30391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 2729*30391Skarels if (q_keyboard.lock) 2730*30391Skarels led_control(qd, LK_LED_ENABLE, LK_LED_LOCK); 2731*30391Skarels else 2732*30391Skarels led_control(qd, LK_LED_DISABLE, LK_LED_LOCK); 2733*30391Skarels return; 2734*30391Skarels 2735*30391Skarels case SHIFT: 2736*30391Skarels q_keyboard.shift ^= 0xFFFF; 2737*30391Skarels return; 2738*30391Skarels 2739*30391Skarels case CNTRL: 2740*30391Skarels q_keyboard.cntrl ^= 0xFFFF; 2741*30391Skarels return; 2742*30391Skarels 2743*30391Skarels case ALLUP: 2744*30391Skarels q_keyboard.cntrl = 0; 2745*30391Skarels q_keyboard.shift = 0; 2746*30391Skarels return; 2747*30391Skarels 2748*30391Skarels case REPEAT: 2749*30391Skarels chr = q_keyboard.last; 2750*30391Skarels break; 2751*30391Skarels 2752*30391Skarels /*------------------------------------------------------- 2753*30391Skarels * Test for cntrl characters. If set, see if the character 2754*30391Skarels * is elligible to become a control character. */ 2755*30391Skarels 2756*30391Skarels default: 2757*30391Skarels 2758*30391Skarels if (q_keyboard.cntrl) { 2759*30391Skarels chr = q_key[key]; 2760*30391Skarels if (chr >= ' ' && chr <= '~') 2761*30391Skarels chr &= 0x1F; 2762*30391Skarels } 2763*30391Skarels else if( q_keyboard.lock || q_keyboard.shift ) 2764*30391Skarels chr = q_shift_key[key]; 2765*30391Skarels else 2766*30391Skarels chr = q_key[key]; 2767*30391Skarels break; 2768*30391Skarels } 2769*30391Skarels 2770*30391Skarels q_keyboard.last = chr; 2771*30391Skarels 2772*30391Skarels /*----------------------------------- 2773*30391Skarels * Check for special function keys */ 2774*30391Skarels 2775*30391Skarels if (chr & 0x80) { 2776*30391Skarels char *string; 2777*30391Skarels string = q_special[chr & 0x7F]; 2778*30391Skarels while(*string) 2779*30391Skarels (*linesw[tp->t_line].l_rint)(*string++, tp); 2780*30391Skarels } 2781*30391Skarels else { 2782*30391Skarels (*linesw[tp->t_line].l_rint)(chr, tp); 2783*30391Skarels } 2784*30391Skarels } 2785*30391Skarels } 2786*30391Skarels 2787*30391Skarels /*---------------------- 2788*30391Skarels * cleanup and exit */ 2789*30391Skarels 2790*30391Skarels return(0); 2791*30391Skarels 2792*30391Skarels } /* qdiint */ 2793*30391Skarels 2794*30391Skarels /****************************************************************** 2795*30391Skarels ******************************************************************* 2796*30391Skarels ******************************************************************* 2797*30391Skarels * 2798*30391Skarels * THE SUBROUTINES START HERE: 2799*30391Skarels * 2800*30391Skarels ******************************************************************/ 2801*30391Skarels 2802*30391Skarels /***************************************************************** 2803*30391Skarels * 2804*30391Skarels * clear_qd_screen()... clear the QDSS screen 2805*30391Skarels * 2806*30391Skarels ****************************************************************** 2807*30391Skarels * 2808*30391Skarels * >>> NOTE <<< 2809*30391Skarels * 2810*30391Skarels * This code requires that certain adder initialization be valid. To 2811*30391Skarels * assure that this requirement is satisfied, this routine should be 2812*30391Skarels * called only after calling the "setup_dragon()" function. 2813*30391Skarels * 2814*30391Skarels * Clear the bitmap a piece at a time. Since the fast scroll clear 2815*30391Skarels * only clears the current displayed portion of the bitmap put a 2816*30391Skarels * temporary value in the y limit register so we can access whole 2817*30391Skarels * bitmap 2818*30391Skarels * 2819*30391Skarels ****************/ 2820*30391Skarels 2821*30391Skarels clear_qd_screen(unit) 2822*30391Skarels int unit; 2823*30391Skarels { 2824*30391Skarels register struct adder *adder; 2825*30391Skarels adder = (struct adder *) qdmap[unit].adder; 2826*30391Skarels 2827*30391Skarels adder->x_limit = 1024; 2828*30391Skarels adder->y_limit = 2048 - CHAR_HEIGHT; 2829*30391Skarels adder->y_offset_pending = 0; 2830*30391Skarels 2831*30391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 2832*30391Skarels wait_status(adder, VSYNC); 2833*30391Skarels 2834*30391Skarels adder->y_scroll_constant = SCROLL_ERASE; 2835*30391Skarels 2836*30391Skarels wait_status(adder, VSYNC); 2837*30391Skarels wait_status(adder, VSYNC); 2838*30391Skarels 2839*30391Skarels adder->y_offset_pending = 864; 2840*30391Skarels 2841*30391Skarels wait_status(adder, VSYNC); 2842*30391Skarels wait_status(adder, VSYNC); 2843*30391Skarels 2844*30391Skarels adder->y_scroll_constant = SCROLL_ERASE; 2845*30391Skarels 2846*30391Skarels wait_status(adder, VSYNC); 2847*30391Skarels wait_status(adder, VSYNC); 2848*30391Skarels 2849*30391Skarels adder->y_offset_pending = 1728; 2850*30391Skarels 2851*30391Skarels wait_status(adder, VSYNC); 2852*30391Skarels wait_status(adder, VSYNC); 2853*30391Skarels 2854*30391Skarels adder->y_scroll_constant = SCROLL_ERASE; 2855*30391Skarels 2856*30391Skarels wait_status(adder, VSYNC); 2857*30391Skarels wait_status(adder, VSYNC); 2858*30391Skarels 2859*30391Skarels adder->y_offset_pending = 0; /* back to normal */ 2860*30391Skarels 2861*30391Skarels wait_status(adder, VSYNC); 2862*30391Skarels wait_status(adder, VSYNC); 2863*30391Skarels 2864*30391Skarels adder->x_limit = MAX_SCREEN_X; 2865*30391Skarels adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; 2866*30391Skarels 2867*30391Skarels } /* clear_qd_screen */ 2868*30391Skarels 2869*30391Skarels /********************************************************************** 2870*30391Skarels * 2871*30391Skarels * qdputc()... route kernel console output to display destination 2872*30391Skarels * 2873*30391Skarels *********************************************************************** 2874*30391Skarels * 2875*30391Skarels * calling convention: 2876*30391Skarels * 2877*30391Skarels * qdputc(chr); 2878*30391Skarels * 2879*30391Skarels * where: char chr; ;character for output 2880*30391Skarels * 2881*30391Skarels ****************/ 2882*30391Skarels 2883*30391Skarels qdputc(chr) 2884*30391Skarels register char chr; 2885*30391Skarels { 2886*30391Skarels register struct tty *tp0; 2887*30391Skarels 2888*30391Skarels /*--------------------------------------------------------- 2889*30391Skarels * if system is now physical, forget it (ie: crash DUMP) */ 2890*30391Skarels 2891*30391Skarels if ( (mfpr(MAPEN) & 1) == 0 ) 2892*30391Skarels return; 2893*30391Skarels 2894*30391Skarels /*-------------------------------------------------- 2895*30391Skarels * direct kernel output char to the proper place */ 2896*30391Skarels 2897*30391Skarels tp0 = &qd_tty[1]; 2898*30391Skarels 2899*30391Skarels if (qdflags[0].kernel_loop != 0 && tp0->t_state & TS_ISOPEN) { 2900*30391Skarels (*linesw[tp0->t_line].l_rint)(chr, tp0); 2901*30391Skarels } else { 2902*30391Skarels blitc(0, chr & 0xff); 2903*30391Skarels } 2904*30391Skarels 2905*30391Skarels } /* qdputc */ 2906*30391Skarels 2907*30391Skarels /******************************************************************* 2908*30391Skarels * 2909*30391Skarels * qdgetc()... get a character from the LK201 2910*30391Skarels * 2911*30391Skarels ******************************************************************* 2912*30391Skarels * 2913*30391Skarels * calling convention: 2914*30391Skarels * 2915*30391Skarels * qdgetc(); 2916*30391Skarels * 2917*30391Skarels * returns: the character read. 2918*30391Skarels * 2919*30391Skarels ****************/ 2920*30391Skarels 2921*30391Skarels qdgetc() 2922*30391Skarels { 2923*30391Skarels register short key; 2924*30391Skarels register char chr; 2925*30391Skarels register struct duart *duart; 2926*30391Skarels 2927*30391Skarels u_int status; 2928*30391Skarels 2929*30391Skarels duart = (struct duart *) qdmap[0].duart; 2930*30391Skarels 2931*30391Skarels /*-------------------------------------- 2932*30391Skarels * Get a character from the keyboard. */ 2933*30391Skarels 2934*30391Skarels LOOP: 2935*30391Skarels while (!((status = duart->statusA) & RCV_RDY)) 2936*30391Skarels ; 2937*30391Skarels 2938*30391Skarels key = duart->dataA; 2939*30391Skarels key &= 0xFF; 2940*30391Skarels 2941*30391Skarels /*-------------------------------------- 2942*30391Skarels * Check for various keyboard errors */ 2943*30391Skarels 2944*30391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 2945*30391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2946*30391Skarels printf("Keyboard error, code = %x\n", key); 2947*30391Skarels return(0); 2948*30391Skarels } 2949*30391Skarels 2950*30391Skarels if (key < LK_LOWEST) 2951*30391Skarels return(0); 2952*30391Skarels 2953*30391Skarels /*--------------------------------- 2954*30391Skarels * See if its a state change key */ 2955*30391Skarels 2956*30391Skarels switch (key) { 2957*30391Skarels 2958*30391Skarels case LOCK: 2959*30391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 2960*30391Skarels if (q_keyboard.lock) 2961*30391Skarels led_control(LK_LED_ENABLE, LK_LED_LOCK); 2962*30391Skarels else 2963*30391Skarels led_control(LK_LED_DISABLE, LK_LED_LOCK); 2964*30391Skarels goto LOOP; 2965*30391Skarels 2966*30391Skarels case SHIFT: 2967*30391Skarels q_keyboard.shift ^= 0xFFFF; 2968*30391Skarels goto LOOP; 2969*30391Skarels 2970*30391Skarels case CNTRL: 2971*30391Skarels q_keyboard.cntrl ^= 0xFFFF; 2972*30391Skarels goto LOOP; 2973*30391Skarels 2974*30391Skarels case ALLUP: 2975*30391Skarels q_keyboard.cntrl = 0; 2976*30391Skarels q_keyboard.shift = 0; 2977*30391Skarels goto LOOP; 2978*30391Skarels 2979*30391Skarels case REPEAT: 2980*30391Skarels chr = q_keyboard.last; 2981*30391Skarels break; 2982*30391Skarels 2983*30391Skarels /*------------------------------------------------------- 2984*30391Skarels * Test for cntrl characters. If set, see if the character 2985*30391Skarels * is elligible to become a control character. */ 2986*30391Skarels 2987*30391Skarels default: 2988*30391Skarels 2989*30391Skarels if (q_keyboard.cntrl) { 2990*30391Skarels chr = q_key[key]; 2991*30391Skarels if (chr >= ' ' && chr <= '~') 2992*30391Skarels chr &= 0x1F; 2993*30391Skarels } 2994*30391Skarels else if ( q_keyboard.lock || q_keyboard.shift ) 2995*30391Skarels chr = q_shift_key[key]; 2996*30391Skarels else 2997*30391Skarels chr = q_key[key]; 2998*30391Skarels break; 2999*30391Skarels } 3000*30391Skarels 3001*30391Skarels if (chr < ' ' && chr > '~') /* if input is non-displayable */ 3002*30391Skarels return(0); /* ..then pitch it! */ 3003*30391Skarels 3004*30391Skarels q_keyboard.last = chr; 3005*30391Skarels 3006*30391Skarels /*----------------------------------- 3007*30391Skarels * Check for special function keys */ 3008*30391Skarels 3009*30391Skarels if (chr & 0x80) /* pitch the function keys */ 3010*30391Skarels return(0); 3011*30391Skarels else 3012*30391Skarels return(chr); 3013*30391Skarels 3014*30391Skarels } /* qdgetc */ 3015*30391Skarels 3016*30391Skarels /********************************************************************** 3017*30391Skarels * 3018*30391Skarels * ldcursor()... load the mouse cursor's template RAM bitmap 3019*30391Skarels * 3020*30391Skarels ********************************************************************* 3021*30391Skarels * 3022*30391Skarels * calling convention: 3023*30391Skarels * 3024*30391Skarels * ldcursor(unit, bitmap); 3025*30391Skarels * u_int unit; 3026*30391Skarels * short *bitmap; 3027*30391Skarels * 3028*30391Skarels ****************/ 3029*30391Skarels 3030*30391Skarels ldcursor(unit, bitmap) 3031*30391Skarels u_int unit; 3032*30391Skarels short *bitmap; 3033*30391Skarels { 3034*30391Skarels register struct dga *dga; 3035*30391Skarels register short *temp; 3036*30391Skarels register int i; 3037*30391Skarels 3038*30391Skarels int cursor; 3039*30391Skarels 3040*30391Skarels dga = (struct dga *) qdmap[unit].dga; 3041*30391Skarels temp = (short *) qdmap[unit].template; 3042*30391Skarels 3043*30391Skarels if (dga->csr & CURS_ENB) { /* if the cursor is enabled.. */ 3044*30391Skarels cursor = -1; /* ..note that.. */ 3045*30391Skarels dga->csr &= ~CURS_ENB; /* ..and shut it off */ 3046*30391Skarels } 3047*30391Skarels else { 3048*30391Skarels cursor = 0; 3049*30391Skarels } 3050*30391Skarels 3051*30391Skarels dga->csr &= ~CURS_ENB; /* shut off the cursor */ 3052*30391Skarels 3053*30391Skarels temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ 3054*30391Skarels /* ..of the 8k WORD template space */ 3055*30391Skarels for (i = 0; i < 32; ++i) 3056*30391Skarels *temp++ = *bitmap++; 3057*30391Skarels 3058*30391Skarels if (cursor) { /* if cursor was enabled.. */ 3059*30391Skarels dga->csr |= CURS_ENB; /* ..turn it back on */ 3060*30391Skarels } 3061*30391Skarels 3062*30391Skarels return(0); 3063*30391Skarels 3064*30391Skarels } /* ldcursor */ 3065*30391Skarels 3066*30391Skarels /********************************************************************** 3067*30391Skarels * 3068*30391Skarels * ldfont()... put the console font in the QDSS off-screen memory 3069*30391Skarels * 3070*30391Skarels *********************************************************************** 3071*30391Skarels * 3072*30391Skarels * calling convention: 3073*30391Skarels * 3074*30391Skarels * ldfont(unit); 3075*30391Skarels * u_int unit; ;QDSS unit number 3076*30391Skarels * 3077*30391Skarels ****************/ 3078*30391Skarels 3079*30391Skarels ldfont(unit) 3080*30391Skarels u_int unit; 3081*30391Skarels { 3082*30391Skarels register struct adder *adder; 3083*30391Skarels 3084*30391Skarels int i; /* scratch variables */ 3085*30391Skarels int j; 3086*30391Skarels int k; 3087*30391Skarels short packed; 3088*30391Skarels 3089*30391Skarels adder = (struct adder *) qdmap[unit].adder; 3090*30391Skarels 3091*30391Skarels /*------------------------------------------ 3092*30391Skarels * setup VIPER operand control registers */ 3093*30391Skarels 3094*30391Skarels write_ID(adder, MASK_1, 0xFFFF); 3095*30391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 3096*30391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 3097*30391Skarels 3098*30391Skarels write_ID(adder, SRC1_OCR_B, 3099*30391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 3100*30391Skarels write_ID(adder, SRC2_OCR_B, 3101*30391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 3102*30391Skarels write_ID(adder, DST_OCR_B, 3103*30391Skarels EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 3104*30391Skarels 3105*30391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 3106*30391Skarels 3107*30391Skarels /*-------------------------- 3108*30391Skarels * load destination data */ 3109*30391Skarels 3110*30391Skarels wait_status(adder, RASTEROP_COMPLETE); 3111*30391Skarels 3112*30391Skarels adder->destination_x = FONT_X; 3113*30391Skarels adder->destination_y = FONT_Y; 3114*30391Skarels adder->fast_dest_dx = FONT_WIDTH; 3115*30391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 3116*30391Skarels 3117*30391Skarels /*--------------------------------------- 3118*30391Skarels * setup for processor to bitmap xfer */ 3119*30391Skarels 3120*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 3121*30391Skarels adder->cmd = PBT | OCRB | 2 | DTE | 2; 3122*30391Skarels 3123*30391Skarels /*----------------------------------------------- 3124*30391Skarels * iteratively do the processor to bitmap xfer */ 3125*30391Skarels 3126*30391Skarels for (i = 0; i < ROWS; ++i) { 3127*30391Skarels 3128*30391Skarels /* PTOB a scan line */ 3129*30391Skarels 3130*30391Skarels for (j = 0, k = i; j < 48; ++j) { 3131*30391Skarels 3132*30391Skarels /* PTOB one scan of a char cell */ 3133*30391Skarels 3134*30391Skarels packed = q_font[k]; 3135*30391Skarels k += ROWS; 3136*30391Skarels packed |= ((short)q_font[k] << 8); 3137*30391Skarels k += ROWS; 3138*30391Skarels 3139*30391Skarels wait_status(adder, TX_READY); 3140*30391Skarels adder->id_data = packed; 3141*30391Skarels } 3142*30391Skarels } 3143*30391Skarels 3144*30391Skarels } /* ldfont */ 3145*30391Skarels 3146*30391Skarels /********************************************************************* 3147*30391Skarels * 3148*30391Skarels * led_control()... twiddle LK-201 LED's 3149*30391Skarels * 3150*30391Skarels ********************************************************************** 3151*30391Skarels * 3152*30391Skarels * led_control(unit, cmd, led_mask); 3153*30391Skarels * u_int unit; QDSS number 3154*30391Skarels * int cmd; LED enable/disable command 3155*30391Skarels * int led_mask; which LED(s) to twiddle 3156*30391Skarels * 3157*30391Skarels *************/ 3158*30391Skarels 3159*30391Skarels led_control(unit, cmd, led_mask) 3160*30391Skarels u_int unit; 3161*30391Skarels int cmd; 3162*30391Skarels int led_mask; 3163*30391Skarels { 3164*30391Skarels register int i; 3165*30391Skarels register int status; 3166*30391Skarels register struct duart *duart; 3167*30391Skarels 3168*30391Skarels duart = (struct duart *) qdmap[unit].duart; 3169*30391Skarels 3170*30391Skarels for (i = 1000; i > 0; --i) { 3171*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 3172*30391Skarels duart->dataA = cmd; 3173*30391Skarels break; 3174*30391Skarels } 3175*30391Skarels } 3176*30391Skarels 3177*30391Skarels for (i = 1000; i > 0; --i) { 3178*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 3179*30391Skarels duart->dataA = led_mask; 3180*30391Skarels break; 3181*30391Skarels } 3182*30391Skarels } 3183*30391Skarels 3184*30391Skarels if (i == 0) 3185*30391Skarels return(BAD); 3186*30391Skarels 3187*30391Skarels return(GOOD); 3188*30391Skarels 3189*30391Skarels } /* led_control */ 3190*30391Skarels 3191*30391Skarels /******************************************************************* 3192*30391Skarels * 3193*30391Skarels * scroll_up()... move the screen up one character height 3194*30391Skarels * 3195*30391Skarels ******************************************************************** 3196*30391Skarels * 3197*30391Skarels * calling convention: 3198*30391Skarels * 3199*30391Skarels * scroll_up(adder); 3200*30391Skarels * struct adder *adder; ;address of adder 3201*30391Skarels * 3202*30391Skarels ********/ 3203*30391Skarels 3204*30391Skarels scroll_up(adder) 3205*30391Skarels register struct adder *adder; 3206*30391Skarels { 3207*30391Skarels 3208*30391Skarels /*------------------------------------------ 3209*30391Skarels * setup VIPER operand control registers */ 3210*30391Skarels 3211*30391Skarels wait_status(adder, ADDRESS_COMPLETE); 3212*30391Skarels 3213*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 3214*30391Skarels 3215*30391Skarels write_ID(adder, MASK_1, 0xFFFF); 3216*30391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 3217*30391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 3218*30391Skarels 3219*30391Skarels write_ID(adder, SRC1_OCR_B, 3220*30391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 3221*30391Skarels write_ID(adder, DST_OCR_B, 3222*30391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 3223*30391Skarels 3224*30391Skarels /*---------------------------------------- 3225*30391Skarels * load DESTINATION origin and vectors */ 3226*30391Skarels 3227*30391Skarels adder->fast_dest_dy = 0; 3228*30391Skarels adder->slow_dest_dx = 0; 3229*30391Skarels adder->error_1 = 0; 3230*30391Skarels adder->error_2 = 0; 3231*30391Skarels 3232*30391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 3233*30391Skarels 3234*30391Skarels adder->destination_x = 0; 3235*30391Skarels adder->fast_dest_dx = 1024; 3236*30391Skarels 3237*30391Skarels adder->destination_y = 0; 3238*30391Skarels adder->slow_dest_dy = 864 - CHAR_HEIGHT; 3239*30391Skarels 3240*30391Skarels /*----------------------------------- 3241*30391Skarels * load SOURCE origin and vectors */ 3242*30391Skarels 3243*30391Skarels adder->source_1_x = 0; 3244*30391Skarels adder->source_1_dx = 1024; 3245*30391Skarels 3246*30391Skarels adder->source_1_y = 0 + CHAR_HEIGHT; 3247*30391Skarels adder->source_1_dy = 864 - CHAR_HEIGHT; 3248*30391Skarels 3249*30391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 3250*30391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 3251*30391Skarels 3252*30391Skarels /*-------------------------------------------- 3253*30391Skarels * do a rectangle clear of last screen line */ 3254*30391Skarels 3255*30391Skarels write_ID(adder, MASK_1, 0xffff); 3256*30391Skarels write_ID(adder, SOURCE, 0xffff); 3257*30391Skarels write_ID(adder,DST_OCR_B, 3258*30391Skarels (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); 3259*30391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); 3260*30391Skarels adder->error_1 = 0; 3261*30391Skarels adder->error_2 = 0; 3262*30391Skarels adder->slow_dest_dx = 0; /* set up the width of */ 3263*30391Skarels adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ 3264*30391Skarels 3265*30391Skarels adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; 3266*30391Skarels wait_status(adder, RASTEROP_COMPLETE); 3267*30391Skarels adder->destination_x = 0; 3268*30391Skarels adder->destination_y = 864 - CHAR_HEIGHT; 3269*30391Skarels 3270*30391Skarels adder->fast_dest_dx = 1024; /* set up the height */ 3271*30391Skarels adder->fast_dest_dy = 0; /* of rectangle */ 3272*30391Skarels 3273*30391Skarels write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); 3274*30391Skarels adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; 3275*30391Skarels 3276*30391Skarels } /* scroll_up */ 3277*30391Skarels 3278*30391Skarels /******************************************************************** 3279*30391Skarels * 3280*30391Skarels * init_shared()... init shared memory pointers and structures 3281*30391Skarels * 3282*30391Skarels ********************************************************************* 3283*30391Skarels * 3284*30391Skarels * calling convention: 3285*30391Skarels * 3286*30391Skarels * init_shared(unit); 3287*30391Skarels * u_int unit; 3288*30391Skarels * 3289*30391Skarels ****************/ 3290*30391Skarels 3291*30391Skarels init_shared(unit) 3292*30391Skarels register u_int unit; 3293*30391Skarels { 3294*30391Skarels register struct dga *dga; 3295*30391Skarels 3296*30391Skarels dga = (struct dga *) qdmap[unit].dga; 3297*30391Skarels 3298*30391Skarels /*-------------------------------------------------- 3299*30391Skarels * initialize the event queue pointers and header */ 3300*30391Skarels 3301*30391Skarels eq_header[unit] = (struct qdinput *) 3302*30391Skarels ((((int)event_shared & ~(0x01FF)) + 512) 3303*30391Skarels + (EVENT_BUFSIZE * unit)); 3304*30391Skarels 3305*30391Skarels eq_header[unit]->curs_pos.x = 0; 3306*30391Skarels eq_header[unit]->curs_pos.y = 0; 3307*30391Skarels 3308*30391Skarels dga->x_cursor = TRANX(eq_header[unit]->curs_pos.x); 3309*30391Skarels dga->y_cursor = TRANY(eq_header[unit]->curs_pos.y); 3310*30391Skarels 3311*30391Skarels eq_header[unit]->curs_box.left = 0; 3312*30391Skarels eq_header[unit]->curs_box.right = 0; 3313*30391Skarels eq_header[unit]->curs_box.top = 0; 3314*30391Skarels eq_header[unit]->curs_box.bottom = 0; 3315*30391Skarels 3316*30391Skarels /*--------------------------------------------------------- 3317*30391Skarels * assign a pointer to the DMA I/O buffer for this QDSS. */ 3318*30391Skarels 3319*30391Skarels DMAheader[unit] = (struct DMAreq_header *) 3320*30391Skarels (((int)(&DMA_shared[0] + 512) & ~0x1FF) 3321*30391Skarels + (DMAbuf_size * unit)); 3322*30391Skarels 3323*30391Skarels DMAheader[unit]->DMAreq = (struct DMAreq *) ((int)DMAheader[unit] 3324*30391Skarels + sizeof(struct DMAreq_header)); 3325*30391Skarels 3326*30391Skarels DMAheader[unit]->QBAreg = 0; 3327*30391Skarels DMAheader[unit]->status = 0; 3328*30391Skarels DMAheader[unit]->shared_size = DMAbuf_size; 3329*30391Skarels DMAheader[unit]->used = 0; 3330*30391Skarels DMAheader[unit]->size = 10; /* default = 10 requests */ 3331*30391Skarels DMAheader[unit]->oldest = 0; 3332*30391Skarels DMAheader[unit]->newest = 0; 3333*30391Skarels 3334*30391Skarels /*----------------------------------------------------------- 3335*30391Skarels * assign a pointer to the scroll structure for this QDSS. */ 3336*30391Skarels 3337*30391Skarels scroll[unit] = (struct scroll *) 3338*30391Skarels (((int)(&scroll_shared[0] + 512) & ~0x1FF) 3339*30391Skarels + (sizeof(struct scroll) * unit)); 3340*30391Skarels 3341*30391Skarels scroll[unit]->status = 0; 3342*30391Skarels scroll[unit]->viper_constant = 0; 3343*30391Skarels scroll[unit]->y_scroll_constant = 0; 3344*30391Skarels scroll[unit]->y_offset = 0; 3345*30391Skarels scroll[unit]->x_index_pending = 0; 3346*30391Skarels scroll[unit]->y_index_pending = 0; 3347*30391Skarels 3348*30391Skarels /*---------------------------------------------------------------- 3349*30391Skarels * assign a pointer to the color map write buffer for this QDSS */ 3350*30391Skarels 3351*30391Skarels color_buf[unit] = (struct color_buf *) 3352*30391Skarels (((int)(&color_shared[0] + 512) & ~0x1FF) 3353*30391Skarels + (COLOR_BUFSIZ * unit)); 3354*30391Skarels 3355*30391Skarels color_buf[unit]->status = 0; 3356*30391Skarels color_buf[unit]->count = 0; 3357*30391Skarels 3358*30391Skarels } /* init_shared */ 3359*30391Skarels 3360*30391Skarels /********************************************************************* 3361*30391Skarels * 3362*30391Skarels * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map 3363*30391Skarels * 3364*30391Skarels ********************************************************************** 3365*30391Skarels * 3366*30391Skarels * calling convention: 3367*30391Skarels * 3368*30391Skarels * setup_dragon(); 3369*30391Skarels * 3370*30391Skarels * return: NONE 3371*30391Skarels * 3372*30391Skarels ************************/ 3373*30391Skarels 3374*30391Skarels setup_dragon(unit) 3375*30391Skarels u_int unit; 3376*30391Skarels { 3377*30391Skarels 3378*30391Skarels register struct adder *adder; 3379*30391Skarels register struct dga *dga; 3380*30391Skarels short *memcsr; 3381*30391Skarels 3382*30391Skarels int i; /* general purpose variables */ 3383*30391Skarels int status; 3384*30391Skarels 3385*30391Skarels short top; /* clipping/scrolling boundaries */ 3386*30391Skarels short bottom; 3387*30391Skarels short right; 3388*30391Skarels short left; 3389*30391Skarels 3390*30391Skarels short *red; /* color map pointers */ 3391*30391Skarels short *green; 3392*30391Skarels short *blue; 3393*30391Skarels 3394*30391Skarels /*------------------ 3395*30391Skarels * init for setup */ 3396*30391Skarels 3397*30391Skarels adder = (struct adder *) qdmap[unit].adder; 3398*30391Skarels dga = (struct dga *) qdmap[unit].dga; 3399*30391Skarels memcsr = (short *) qdmap[unit].memcsr; 3400*30391Skarels 3401*30391Skarels dga->csr &= ~(DMA_IE | 0x700); /* halt DMA and kill the intrpts */ 3402*30391Skarels *memcsr = SYNC_ON; /* blank screen and turn off LED's */ 3403*30391Skarels adder->command = CANCEL; 3404*30391Skarels 3405*30391Skarels /*---------------------- 3406*30391Skarels * set monitor timing */ 3407*30391Skarels 3408*30391Skarels adder->x_scan_count_0 = 0x2800; 3409*30391Skarels adder->x_scan_count_1 = 0x1020; 3410*30391Skarels adder->x_scan_count_2 = 0x003A; 3411*30391Skarels adder->x_scan_count_3 = 0x38F0; 3412*30391Skarels adder->x_scan_count_4 = 0x6128; 3413*30391Skarels adder->x_scan_count_5 = 0x093A; 3414*30391Skarels adder->x_scan_count_6 = 0x313C; 3415*30391Skarels adder->sync_phase_adj = 0x0100; 3416*30391Skarels adder->x_scan_conf = 0x00C8; 3417*30391Skarels 3418*30391Skarels /*--------------------------------------------------------- 3419*30391Skarels * got a bug in secound pass ADDER! lets take care of it */ 3420*30391Skarels 3421*30391Skarels /* normally, just use the code in the following bug fix code, but to 3422*30391Skarels * make repeated demos look pretty, load the registers as if there was 3423*30391Skarels * no bug and then test to see if we are getting sync */ 3424*30391Skarels 3425*30391Skarels adder->y_scan_count_0 = 0x135F; 3426*30391Skarels adder->y_scan_count_1 = 0x3363; 3427*30391Skarels adder->y_scan_count_2 = 0x2366; 3428*30391Skarels adder->y_scan_count_3 = 0x0388; 3429*30391Skarels 3430*30391Skarels /* if no sync, do the bug fix code */ 3431*30391Skarels 3432*30391Skarels if (wait_status(adder, VSYNC) == BAD) { 3433*30391Skarels 3434*30391Skarels /* first load all Y scan registers with very short frame and 3435*30391Skarels * wait for scroll service. This guarantees at least one SYNC 3436*30391Skarels * to fix the pass 2 Adder initialization bug (synchronizes 3437*30391Skarels * XCINCH with DMSEEDH) */ 3438*30391Skarels 3439*30391Skarels adder->y_scan_count_0 = 0x01; 3440*30391Skarels adder->y_scan_count_1 = 0x01; 3441*30391Skarels adder->y_scan_count_2 = 0x01; 3442*30391Skarels adder->y_scan_count_3 = 0x01; 3443*30391Skarels 3444*30391Skarels wait_status(adder, VSYNC); /* delay at least 1 full frame time */ 3445*30391Skarels wait_status(adder, VSYNC); 3446*30391Skarels 3447*30391Skarels /* now load the REAL sync values (in reverse order just to 3448*30391Skarels * be safe. */ 3449*30391Skarels 3450*30391Skarels adder->y_scan_count_3 = 0x0388; 3451*30391Skarels adder->y_scan_count_2 = 0x2366; 3452*30391Skarels adder->y_scan_count_1 = 0x3363; 3453*30391Skarels adder->y_scan_count_0 = 0x135F; 3454*30391Skarels } 3455*30391Skarels 3456*30391Skarels *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ 3457*30391Skarels 3458*30391Skarels /*---------------------------- 3459*30391Skarels * zero the index registers */ 3460*30391Skarels 3461*30391Skarels adder->x_index_pending = 0; 3462*30391Skarels adder->y_index_pending = 0; 3463*30391Skarels adder->x_index_new = 0; 3464*30391Skarels adder->y_index_new = 0; 3465*30391Skarels adder->x_index_old = 0; 3466*30391Skarels adder->y_index_old = 0; 3467*30391Skarels 3468*30391Skarels adder->pause = 0; 3469*30391Skarels 3470*30391Skarels /*---------------------------------------- 3471*30391Skarels * set rasterop mode to normal pen down */ 3472*30391Skarels 3473*30391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 3474*30391Skarels 3475*30391Skarels /*-------------------------------------------------- 3476*30391Skarels * set the rasterop registers to a default values */ 3477*30391Skarels 3478*30391Skarels adder->source_1_dx = 1; 3479*30391Skarels adder->source_1_dy = 1; 3480*30391Skarels adder->source_1_x = 0; 3481*30391Skarels adder->source_1_y = 0; 3482*30391Skarels adder->destination_x = 0; 3483*30391Skarels adder->destination_y = 0; 3484*30391Skarels adder->fast_dest_dx = 1; 3485*30391Skarels adder->fast_dest_dy = 0; 3486*30391Skarels adder->slow_dest_dx = 0; 3487*30391Skarels adder->slow_dest_dy = 1; 3488*30391Skarels adder->error_1 = 0; 3489*30391Skarels adder->error_2 = 0; 3490*30391Skarels 3491*30391Skarels /*------------------------ 3492*30391Skarels * scale factor = unity */ 3493*30391Skarels 3494*30391Skarels adder->fast_scale = UNITY; 3495*30391Skarels adder->slow_scale = UNITY; 3496*30391Skarels 3497*30391Skarels /*------------------------------- 3498*30391Skarels * set the source 2 parameters */ 3499*30391Skarels 3500*30391Skarels adder->source_2_x = 0; 3501*30391Skarels adder->source_2_y = 0; 3502*30391Skarels adder->source_2_size = 0x0022; 3503*30391Skarels 3504*30391Skarels /*----------------------------------------------- 3505*30391Skarels * initialize plane addresses for eight vipers */ 3506*30391Skarels 3507*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 3508*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0000); 3509*30391Skarels 3510*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0002); 3511*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0001); 3512*30391Skarels 3513*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0004); 3514*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0002); 3515*30391Skarels 3516*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0008); 3517*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0003); 3518*30391Skarels 3519*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0010); 3520*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0004); 3521*30391Skarels 3522*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0020); 3523*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0005); 3524*30391Skarels 3525*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0040); 3526*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0006); 3527*30391Skarels 3528*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0080); 3529*30391Skarels write_ID(adder, PLANE_ADDRESS, 0x0007); 3530*30391Skarels 3531*30391Skarels /* initialize the external registers. */ 3532*30391Skarels 3533*30391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); 3534*30391Skarels write_ID(adder, CS_SCROLL_MASK, 0x00FF); 3535*30391Skarels 3536*30391Skarels /* initialize resolution mode */ 3537*30391Skarels 3538*30391Skarels write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ 3539*30391Skarels write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ 3540*30391Skarels 3541*30391Skarels /* initialize viper registers */ 3542*30391Skarels 3543*30391Skarels write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); 3544*30391Skarels write_ID(adder, SCROLL_FILL, 0x0000); 3545*30391Skarels 3546*30391Skarels /*---------------------------------------------------- 3547*30391Skarels * set clipping and scrolling limits to full screen */ 3548*30391Skarels 3549*30391Skarels for ( i = 1000, adder->status = 0 3550*30391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 3551*30391Skarels ; --i); 3552*30391Skarels 3553*30391Skarels if (i == 0) 3554*30391Skarels mprintf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 3555*30391Skarels 3556*30391Skarels top = 0; 3557*30391Skarels bottom = 2048; 3558*30391Skarels left = 0; 3559*30391Skarels right = 1024; 3560*30391Skarels 3561*30391Skarels adder->x_clip_min = left; 3562*30391Skarels adder->x_clip_max = right; 3563*30391Skarels adder->y_clip_min = top; 3564*30391Skarels adder->y_clip_max = bottom; 3565*30391Skarels 3566*30391Skarels adder->scroll_x_min = left; 3567*30391Skarels adder->scroll_x_max = right; 3568*30391Skarels adder->scroll_y_min = top; 3569*30391Skarels adder->scroll_y_max = bottom; 3570*30391Skarels 3571*30391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 3572*30391Skarels wait_status(adder, VSYNC); 3573*30391Skarels 3574*30391Skarels adder->x_index_pending = left; 3575*30391Skarels adder->y_index_pending = top; 3576*30391Skarels adder->x_index_new = left; 3577*30391Skarels adder->y_index_new = top; 3578*30391Skarels adder->x_index_old = left; 3579*30391Skarels adder->y_index_old = top; 3580*30391Skarels 3581*30391Skarels for ( i = 1000, adder->status = 0 3582*30391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 3583*30391Skarels ; --i); 3584*30391Skarels 3585*30391Skarels if (i == 0) 3586*30391Skarels mprintf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 3587*30391Skarels 3588*30391Skarels write_ID(adder, LEFT_SCROLL_MASK, 0x0000); 3589*30391Skarels write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); 3590*30391Skarels 3591*30391Skarels /*------------------------------------------------------------ 3592*30391Skarels * set source and the mask register to all ones (ie: white) */ 3593*30391Skarels 3594*30391Skarels write_ID(adder, SOURCE, 0xFFFF); 3595*30391Skarels write_ID(adder, MASK_1, 0xFFFF); 3596*30391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 3597*30391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 3598*30391Skarels 3599*30391Skarels /*-------------------------------------------------------------- 3600*30391Skarels * initialize Operand Control Register banks for fill command */ 3601*30391Skarels 3602*30391Skarels write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); 3603*30391Skarels write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); 3604*30391Skarels write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 3605*30391Skarels 3606*30391Skarels write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); 3607*30391Skarels write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); 3608*30391Skarels write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 3609*30391Skarels 3610*30391Skarels /*------------------------------------------------------------------ 3611*30391Skarels * init Logic Unit Function registers, (these are just common values, 3612*30391Skarels * and may be changed as required). */ 3613*30391Skarels 3614*30391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 3615*30391Skarels write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); 3616*30391Skarels write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); 3617*30391Skarels write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); 3618*30391Skarels 3619*30391Skarels /*---------------------------------------- 3620*30391Skarels * load the color map for black & white */ 3621*30391Skarels 3622*30391Skarels for ( i = 0, adder->status = 0 3623*30391Skarels ; i < 10000 && !((status = adder->status) & VSYNC) 3624*30391Skarels ; ++i); 3625*30391Skarels 3626*30391Skarels if (i == 0) 3627*30391Skarels mprintf("\nqd%d: setup_dragon: timeout on VSYNC", unit); 3628*30391Skarels 3629*30391Skarels red = (short *) qdmap[unit].red; 3630*30391Skarels green = (short *) qdmap[unit].green; 3631*30391Skarels blue = (short *) qdmap[unit].blue; 3632*30391Skarels 3633*30391Skarels *red++ = 0x00; /* black */ 3634*30391Skarels *green++ = 0x00; 3635*30391Skarels *blue++ = 0x00; 3636*30391Skarels 3637*30391Skarels *red-- = 0xFF; /* white */ 3638*30391Skarels *green-- = 0xFF; 3639*30391Skarels *blue-- = 0xFF; 3640*30391Skarels 3641*30391Skarels /*---------------------------------- 3642*30391Skarels * set color map for mouse cursor */ 3643*30391Skarels 3644*30391Skarels red += 254; 3645*30391Skarels green += 254; 3646*30391Skarels blue += 254; 3647*30391Skarels 3648*30391Skarels *red++ = 0x00; /* black */ 3649*30391Skarels *green++ = 0x00; 3650*30391Skarels *blue++ = 0x00; 3651*30391Skarels 3652*30391Skarels *red = 0xFF; /* white */ 3653*30391Skarels *green = 0xFF; 3654*30391Skarels *blue = 0xFF; 3655*30391Skarels 3656*30391Skarels return(0); 3657*30391Skarels 3658*30391Skarels } /* setup_dragon */ 3659*30391Skarels 3660*30391Skarels /****************************************************************** 3661*30391Skarels * 3662*30391Skarels * setup_input()... init the DUART and set defaults in input 3663*30391Skarels * devices 3664*30391Skarels * 3665*30391Skarels ******************************************************************* 3666*30391Skarels * 3667*30391Skarels * calling convention: 3668*30391Skarels * 3669*30391Skarels * setup_input(unit); 3670*30391Skarels * 3671*30391Skarels * where: unit - is the QDSS unit number to be setup 3672*30391Skarels * 3673*30391Skarels *********/ 3674*30391Skarels 3675*30391Skarels setup_input(unit) 3676*30391Skarels u_int unit; 3677*30391Skarels { 3678*30391Skarels register struct duart *duart; /* DUART register structure pointer */ 3679*30391Skarels register int i; /* scratch variable */ 3680*30391Skarels register int bits; 3681*30391Skarels 3682*30391Skarels char id_byte; 3683*30391Skarels short status; 3684*30391Skarels 3685*30391Skarels /*--------------- 3686*30391Skarels * init stuff */ 3687*30391Skarels 3688*30391Skarels duart = (struct duart *) qdmap[unit].duart; 3689*30391Skarels duart->imask = 0; 3690*30391Skarels 3691*30391Skarels /*--------------------------------------------- 3692*30391Skarels * setup the DUART for kbd & pointing device */ 3693*30391Skarels 3694*30391Skarels duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ 3695*30391Skarels duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ 3696*30391Skarels /* no RTS control,char error mode */ 3697*30391Skarels duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ 3698*30391Skarels /* no RTS control,no echo or loop */ 3699*30391Skarels duart->cmdB = RESET_M; /* reset mode reg pntr for host */ 3700*30391Skarels duart->modeB = 0x07; /* 8 bits, odd parity, rcv IE.. */ 3701*30391Skarels /* ..no RTS cntrl, char error mode */ 3702*30391Skarels duart->modeB = 0x07; /* 1 stop bit,CTS does not IE XMT */ 3703*30391Skarels /* no RTS control,no echo or loop */ 3704*30391Skarels 3705*30391Skarels duart->auxctl = 0x00; /* baud rate set 1 */ 3706*30391Skarels 3707*30391Skarels duart->clkselA = 0x99; /* 4800 baud for kbd */ 3708*30391Skarels duart->clkselB = 0x99; /* 4800 baud for mouse */ 3709*30391Skarels 3710*30391Skarels /* reset everything for keyboard */ 3711*30391Skarels 3712*30391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 3713*30391Skarels duart->cmdA = bits; 3714*30391Skarels 3715*30391Skarels /* reset everything for host */ 3716*30391Skarels 3717*30391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 3718*30391Skarels duart->cmdB = bits; 3719*30391Skarels 3720*30391Skarels duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ 3721*30391Skarels duart->cmdB = EN_RCV | EN_XMT; /* enbl xmt & rcv for pointer device */ 3722*30391Skarels 3723*30391Skarels /*-------------------------------------------- 3724*30391Skarels * init keyboard defaults (DUART channel A) */ 3725*30391Skarels 3726*30391Skarels for (i = 500; i > 0; --i) { 3727*30391Skarels if ((status = duart->statusA) & XMT_RDY) { 3728*30391Skarels duart->dataA = LK_DEFAULTS; 3729*30391Skarels break; 3730*30391Skarels } 3731*30391Skarels } 3732*30391Skarels 3733*30391Skarels for (i = 100000; i > 0; --i) { 3734*30391Skarels if ((status = duart->statusA) & RCV_RDY) { 3735*30391Skarels break; 3736*30391Skarels } 3737*30391Skarels } 3738*30391Skarels 3739*30391Skarels status = duart->dataA; /* flush the ACK */ 3740*30391Skarels 3741*30391Skarels /*-------------------------------- 3742*30391Skarels * identify the pointing device */ 3743*30391Skarels 3744*30391Skarels for (i = 500; i > 0; --i) { 3745*30391Skarels if ((status = duart->statusB) & XMT_RDY) { 3746*30391Skarels duart->dataB = SELF_TEST; 3747*30391Skarels break; 3748*30391Skarels } 3749*30391Skarels } 3750*30391Skarels 3751*30391Skarels /*----------------------------------------- 3752*30391Skarels * wait for 1st byte of self test report */ 3753*30391Skarels 3754*30391Skarels for (i = 100000; i > 0; --i) { 3755*30391Skarels if ((status = duart->statusB) & RCV_RDY) { 3756*30391Skarels break; 3757*30391Skarels } 3758*30391Skarels } 3759*30391Skarels 3760*30391Skarels if (i == 0) { 3761*30391Skarels mprintf("\nqd[%d]: setup_input: timeout on 1st byte of self test",unit); 3762*30391Skarels goto OUT; 3763*30391Skarels } 3764*30391Skarels 3765*30391Skarels status = duart->dataB; 3766*30391Skarels 3767*30391Skarels /*----------------------------------------- 3768*30391Skarels * wait for ID byte of self test report */ 3769*30391Skarels 3770*30391Skarels for (i = 100000; i > 0; --i) { 3771*30391Skarels if ((status = duart->statusB) & RCV_RDY) { 3772*30391Skarels break; 3773*30391Skarels } 3774*30391Skarels } 3775*30391Skarels 3776*30391Skarels if (i == 0) { 3777*30391Skarels mprintf("\nqd[%d]: setup_input: timeout on 2nd byte of self test", unit); 3778*30391Skarels goto OUT; 3779*30391Skarels } 3780*30391Skarels 3781*30391Skarels id_byte = duart->dataB; 3782*30391Skarels 3783*30391Skarels /*------------------------------------ 3784*30391Skarels * wait for other bytes to come in */ 3785*30391Skarels 3786*30391Skarels for (i = 100000; i > 0; --i) { 3787*30391Skarels if ((status = duart->statusB) & RCV_RDY) { 3788*30391Skarels status = duart->dataB; 3789*30391Skarels break; 3790*30391Skarels } 3791*30391Skarels } 3792*30391Skarels 3793*30391Skarels if (i == 0) { 3794*30391Skarels mprintf("\nqd[%d]: setup_input: timeout on 3rd byte of self test", unit); 3795*30391Skarels goto OUT; 3796*30391Skarels } 3797*30391Skarels 3798*30391Skarels for (i = 100000; i > 0; --i) { 3799*30391Skarels if ((status = duart->statusB) & RCV_RDY) { 3800*30391Skarels status = duart->dataB; 3801*30391Skarels break; 3802*30391Skarels } 3803*30391Skarels } 3804*30391Skarels 3805*30391Skarels if (i == 0) { 3806*30391Skarels mprintf("\nqd[%d]: setup_input: timeout on 4th byte of self test\n", unit); 3807*30391Skarels goto OUT; 3808*30391Skarels } 3809*30391Skarels 3810*30391Skarels /*---------------------------------------------- 3811*30391Skarels * flag pointing device type and set defaults */ 3812*30391Skarels 3813*30391Skarels for (i=100000; i>0; --i); 3814*30391Skarels 3815*30391Skarels if ((id_byte & 0x0F) != TABLET_ID) { 3816*30391Skarels 3817*30391Skarels qdflags[unit].pntr_id = MOUSE_ID; 3818*30391Skarels 3819*30391Skarels for (i = 500; i > 0; --i) { 3820*30391Skarels if ((status = duart->statusB) & XMT_RDY) { 3821*30391Skarels duart->dataB = INC_STREAM_MODE; 3822*30391Skarels break; 3823*30391Skarels } 3824*30391Skarels } 3825*30391Skarels } else { 3826*30391Skarels 3827*30391Skarels qdflags[unit].pntr_id = TABLET_ID; 3828*30391Skarels 3829*30391Skarels for (i = 500; i > 0; --i) { 3830*30391Skarels if ((status = duart->statusB) & XMT_RDY) { 3831*30391Skarels duart->dataB = T_STREAM; 3832*30391Skarels break; 3833*30391Skarels } 3834*30391Skarels } 3835*30391Skarels } 3836*30391Skarels 3837*30391Skarels /*-------- 3838*30391Skarels * exit */ 3839*30391Skarels 3840*30391Skarels OUT: 3841*30391Skarels duart->imask = qdflags[unit].duart_imask; 3842*30391Skarels return(0); 3843*30391Skarels 3844*30391Skarels } /* setup_input */ 3845*30391Skarels 3846*30391Skarels /********************************************************************** 3847*30391Skarels * 3848*30391Skarels * wait_status()... delay for at least one display frame time 3849*30391Skarels * 3850*30391Skarels *********************************************************************** 3851*30391Skarels * 3852*30391Skarels * calling convention: 3853*30391Skarels * 3854*30391Skarels * wait_status(adder, mask); 3855*30391Skarels * struct *adder adder; 3856*30391Skarels * int mask; 3857*30391Skarels * 3858*30391Skarels * return: BAD means that we timed out without ever seeing the 3859*30391Skarels * vertical sync status bit 3860*30391Skarels * GOOD otherwise 3861*30391Skarels * 3862*30391Skarels **************/ 3863*30391Skarels 3864*30391Skarels wait_status(adder, mask) 3865*30391Skarels register struct adder *adder; 3866*30391Skarels register int mask; 3867*30391Skarels { 3868*30391Skarels register short status; 3869*30391Skarels int i; 3870*30391Skarels 3871*30391Skarels for ( i = 10000, adder->status = 0 3872*30391Skarels ; i > 0 && !((status = adder->status) & mask) 3873*30391Skarels ; --i); 3874*30391Skarels 3875*30391Skarels if (i == 0) { 3876*30391Skarels mprintf("\nwait_status: timeout polling for 0x%x in adder->status", mask); 3877*30391Skarels return(BAD); 3878*30391Skarels } 3879*30391Skarels 3880*30391Skarels return(GOOD); 3881*30391Skarels 3882*30391Skarels } /* wait_status */ 3883*30391Skarels 3884*30391Skarels /********************************************************************** 3885*30391Skarels * 3886*30391Skarels * write_ID()... write out onto the ID bus 3887*30391Skarels * 3888*30391Skarels *********************************************************************** 3889*30391Skarels * 3890*30391Skarels * calling convention: 3891*30391Skarels * 3892*30391Skarels * struct *adder adder; ;pntr to ADDER structure 3893*30391Skarels * short adrs; ;VIPER address 3894*30391Skarels * short data; ;data to be written 3895*30391Skarels * write_ID(adder); 3896*30391Skarels * 3897*30391Skarels * return: BAD means that we timed out waiting for status bits 3898*30391Skarels * VIPER-access-specific status bits 3899*30391Skarels * GOOD otherwise 3900*30391Skarels * 3901*30391Skarels **************/ 3902*30391Skarels 3903*30391Skarels write_ID(adder, adrs, data) 3904*30391Skarels register struct adder *adder; 3905*30391Skarels register short adrs; 3906*30391Skarels register short data; 3907*30391Skarels { 3908*30391Skarels int i; 3909*30391Skarels short status; 3910*30391Skarels 3911*30391Skarels for ( i = 100000, adder->status = 0 3912*30391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 3913*30391Skarels ; --i); 3914*30391Skarels 3915*30391Skarels if (i == 0) 3916*30391Skarels goto ERR; 3917*30391Skarels 3918*30391Skarels for ( i = 100000, adder->status = 0 3919*30391Skarels ; i > 0 && !((status = adder->status) & TX_READY) 3920*30391Skarels ; --i); 3921*30391Skarels 3922*30391Skarels if (i > 0) { 3923*30391Skarels adder->id_data = data; 3924*30391Skarels adder->command = ID_LOAD | adrs; 3925*30391Skarels return(GOOD); 3926*30391Skarels } 3927*30391Skarels 3928*30391Skarels ERR: 3929*30391Skarels mprintf("\nwrite_ID: timeout trying to write to VIPER"); 3930*30391Skarels return(BAD); 3931*30391Skarels 3932*30391Skarels } /* write_ID */ 3933