1006e9885Smarc /* 2006e9885Smarc * Copyright (c) 1982, 1986 Regents of the University of California. 3006e9885Smarc * All rights reserved. The Berkeley software License Agreement 4006e9885Smarc * specifies the terms and conditions for redistribution. 5006e9885Smarc * 6*e977faadSmarc * @(#)qd.c 1.6 Berkeley 06/01/88 7006e9885Smarc * 8*e977faadSmarc * derived from: "@(#)qd.c ULTRIX"; 9006e9885Smarc */ 107e911b15Skarels /************************************************************************ 117e911b15Skarels * * 12*e977faadSmarc * Copyright (c) 1985-1988 by * 137e911b15Skarels * Digital Equipment Corporation, Maynard, MA * 147e911b15Skarels * All rights reserved. * 157e911b15Skarels * * 167e911b15Skarels * This software is furnished under a license and may be used and * 177e911b15Skarels * copied only in accordance with the terms of such license and * 187e911b15Skarels * with the inclusion of the above copyright notice. This * 197e911b15Skarels * software or any other copies thereof may not be provided or * 207e911b15Skarels * otherwise made available to any other person. No title to and * 217e911b15Skarels * ownership of the software is hereby transferred. * 227e911b15Skarels * * 237e911b15Skarels * The information in this software is subject to change without * 247e911b15Skarels * notice and should not be construed as a commitment by Digital * 257e911b15Skarels * Equipment Corporation. * 267e911b15Skarels * * 277e911b15Skarels * Digital assumes no responsibility for the use or reliability * 287e911b15Skarels * of its software on equipment which is not supplied by Digital. * 297e911b15Skarels * * 307e911b15Skarels *************************************************************************/ 31*e977faadSmarc 327e911b15Skarels /* 33*e977faadSmarc * qd.c 34*e977faadSmarc * 35*e977faadSmarc * Modification history 36*e977faadSmarc * 37*e977faadSmarc * QDSS workstation driver 38*e977faadSmarc * 39*e977faadSmarc * 40*e977faadSmarc * 1-Dec-87 - Tim Burke 41*e977faadSmarc * 42*e977faadSmarc * Added support for both System V termio(7) and POSIX termios(7). These 43*e977faadSmarc * changes also include support for 8-bit canonical processing. Changes 44*e977faadSmarc * involve: 45*e977faadSmarc * 46*e977faadSmarc * - Default settings on first open depend on mode of open. For termio 47*e977faadSmarc * opens the defaults are "RAW" style, while non-termio opens default 48*e977faadSmarc * to the traditional "cooked" style. 49*e977faadSmarc * - The driver now represents its terminal attributes and special 50*e977faadSmarc * characters in the POSIX termios data structure. This contrasts the 51*e977faadSmarc * original approach of storing attributes and special chars in the 52*e977faadSmarc * t_flags, ltchars and tchars. 53*e977faadSmarc * - Addition of LPASS8 to local mode word for 8-bit canonical support. 54*e977faadSmarc * 55*e977faadSmarc * 28-Sep-87 - Ali Rafieymehr 56*e977faadSmarc * Fixed a bug in qddint() routine. The bug was discovered on CVAX. 57*e977faadSmarc * Incorrect logic was used when taking an entry from the request queue. 58*e977faadSmarc * 59*e977faadSmarc * 12-Oct-87 - Tim Burke 60*e977faadSmarc * Modified driver to provide 8-bit support to the console port. To do 61*e977faadSmarc * this characters are defined in the remainder of the first 15 rows of 62*e977faadSmarc * off screen memory as well as in next 15 rows. 63*e977faadSmarc * 64*e977faadSmarc * 2-Aug-87 - Fred Canter 65*e977faadSmarc * Use TANDEM mode on qconsole for flow control of writes to 66*e977faadSmarc * /dev/console. 67*e977faadSmarc * 68*e977faadSmarc * 12-Jun-87 - Tim Burke 69*e977faadSmarc * 70*e977faadSmarc * Added full TERMIO functionality to terminal subsystem. 71*e977faadSmarc * Changed open routine to setup propper default settings if the line 72*e977faadSmarc * is not being used as a graphics device. Added defines of defaults. 73*e977faadSmarc * 74*e977faadSmarc * 75*e977faadSmarc * 14-May-87 - Fred Canter 76*e977faadSmarc * Changed default state of kernel_loop to on. 77*e977faadSmarc * 78*e977faadSmarc * 21-Apr-87 - Brian Stevens 79*e977faadSmarc * Xos support 80*e977faadSmarc * 81*e977faadSmarc * 16-Apr-87 - Fred Canter (for Brian Stevens) 82*e977faadSmarc * Multi-head GPX changes. 83*e977faadSmarc * 84*e977faadSmarc * 19-Mar-87 - Fred Canter (for Brian Stevens) 85*e977faadSmarc * Added X in the kernel support. 86*e977faadSmarc * 87*e977faadSmarc * 16-Dec-86 - Brian Stevens 88*e977faadSmarc * 89*e977faadSmarc * added support so "select" could be called on tty type device 90*e977faadSmarc * fixed rlogin bug 91*e977faadSmarc * 92*e977faadSmarc * 30-Oct-86 - Brian Stevens 93*e977faadSmarc * 94*e977faadSmarc * Removed the mprintf for "unexpected interrupts" 95*e977faadSmarc * 96*e977faadSmarc * 26-Aug-86 - rsp (Ricky Palmer) 97*e977faadSmarc * 98*e977faadSmarc * Cleaned up devioctl code to (1) zero out devget structure 99*e977faadSmarc * upon entry and (2) use strlen instead of fixed storage 100*e977faadSmarc * for bcopy's. 101*e977faadSmarc * 102*e977faadSmarc * 21-Jul-86 - Ram Rao 103*e977faadSmarc * allowed cursor rectangle to hang (partially) off the 104*e977faadSmarc * top and left of screen 105*e977faadSmarc * 106*e977faadSmarc * 11-Jul-86 - ricky palmer 107*e977faadSmarc * 108*e977faadSmarc * Added adpt and nexus fields to DEVIOCGET code. 109*e977faadSmarc * 110*e977faadSmarc * 02-July-86 - Brian Stevens 111*e977faadSmarc * 112*e977faadSmarc * added support for console writing to second QDSS display 113*e977faadSmarc * 114*e977faadSmarc * 20-May-86 - ricky palmer 115*e977faadSmarc * 116*e977faadSmarc * Added new DEVIOCGET ioctl request code. V2.0 117*e977faadSmarc * 118*e977faadSmarc * 16-Apr-86 -- darrell 119*e977faadSmarc * badaddr is now called via the macro BADADDR 120*e977faadSmarc * 121*e977faadSmarc * 14-Apr-86 -- afd 122*e977faadSmarc * Changed UMEMmap to QVmap and umem to qvmem. 123*e977faadSmarc * 124*e977faadSmarc * v_console() is now refered to as v_consputc, and there is a 125*e977faadSmarc * corresponding v_consgetc() (defined in /sys/vax/conf.c). 126*e977faadSmarc * 127*e977faadSmarc * Added "qdgetc()" routine for console read. Needed to read 128*e977faadSmarc * user's answer to the "root device?" prompt with a generic kernel. 129*e977faadSmarc * 130*e977faadSmarc * 19-Mar-86 -- pmk 131*e977faadSmarc * Change DELAY to 20000, because microdelay now in real microsec. 132*e977faadSmarc * 133*e977faadSmarc * 18-mar-86 -- jaw br/cvec changed to NOT use registers. 134*e977faadSmarc * 135*e977faadSmarc * 11 mar 86 darrell replaced percpu with cpusw, and removed all but 136*e977faadSmarc * one global reference 137*e977faadSmarc * 19 feb 86 bstevens no report of motion event on puck/stylus button action 138*e977faadSmarc * 18 feb 86 bstevens put in cursor box support for tablets 139*e977faadSmarc * 18-Mar-86 -- jaw add routines to cpu switch for nexus/unibus addreses 140*e977faadSmarc * also got rid of some globals like nexnum. 141*e977faadSmarc * ka8800 cleanup. 142*e977faadSmarc * 06 dec 85 longo added LK-201 error reporting for graphics device ops 143*e977faadSmarc * 03 dec 85 longo made qddint() clear active bit on error 144*e977faadSmarc * 02 dec 85 longo fixed up some crocks in the error messages 145*e977faadSmarc * 25 nov 85 longo added error handling to DMA ISR and single user locking 146*e977faadSmarc * 19 nov 85 longo eliminated "set_defaults()" by breaking out sub-calls. 147*e977faadSmarc * Changed init_shared to do real init of scroll struct 148*e977faadSmarc * 12 nov 85 longo fixed bug in open that broke alternate console re-direct 149*e977faadSmarc * 11 nov 85 longo changed "_vs_eventqueue" references to "qdinput" 150*e977faadSmarc * 08 nov 85 longo improved select service for read/write select wakeup. 151*e977faadSmarc * Also set ISR's to ipl4 to allow the interval timer in. 152*e977faadSmarc * 04 nov 85 longo fixed bugs in mouse button reporting and dma request stuff 153*e977faadSmarc * 30 oct 85 longo DMA to/from user space is in place 154*e977faadSmarc * 14 oct 85 longo added kernel msg redirect and QD_RDCURSOR ioctl 155*e977faadSmarc * 03 oct 85 longo added support for multiple QDSS's 156*e977faadSmarc * 02 oct 85 longo added color map loading services in qdioctl() & qdaint() 157*e977faadSmarc * 30 sep 85 longo added DMA interrupt services 158*e977faadSmarc * 18 sep 85 longo added scroll services to "qdaint()" adder intrpt service 159*e977faadSmarc * and put in supporting ioctl's 160*e977faadSmarc * 04 sep 85 longo initial implementation of DMA is working 161*e977faadSmarc * 17 aug 85 longo added support for the QDSS to be system console 162*e977faadSmarc * 05 aug 85 longo now using qfont (QVSS & QDSS) as linked object 163*e977faadSmarc * 12 jun 85 longo added mouse event loading to "qdiint()" 164*e977faadSmarc * 31 may 85 longo put live interrupts into the probe() routine 165*e977faadSmarc * 30 may 85 longo event queue shared memory implementation is now alive 166*e977faadSmarc * 29 may 85 longo LK-201 input is now interrupt driven 167*e977faadSmarc * 25 apr 85 longo MAPDEVICE works 168*e977faadSmarc * 14 mar 85 longo created 169*e977faadSmarc * 170*e977faadSmarc * todo: fix rlogin bug in console stuff 171*e977faadSmarc * cat -u console redirection 172*e977faadSmarc * check error return from strategy routine 173*e977faadSmarc * verify TOY time stuff (what format?) 174*e977faadSmarc * look at system based macro implementation of VTOP 175*e977faadSmarc * 1767e911b15Skarels */ 1777e911b15Skarels 178*e977faadSmarc #include "qd.h" /* # of QDSS's the system is configured for */ 179*e977faadSmarc 180006e9885Smarc #if NQD > 0 181*e977faadSmarc #include "types.h" 182*e977faadSmarc #include "../machine/pte.h" /* page table values */ 183*e977faadSmarc #include "../machine/mtpr.h" /* VAX register access stuff */ 184006e9885Smarc #include "../machine/cpu.h" 185*e977faadSmarc #include "param.h" /* general system params & macros */ 186*e977faadSmarc #include "conf.h" /* "linesw" tty driver dispatch */ 187*e977faadSmarc #include "dir.h" /* for directory handling */ 188*e977faadSmarc #include "user.h" /* user structure (what else?) */ 189*e977faadSmarc #include "qdioctl.h" /* ioctl call values */ 190006e9885Smarc #include "tty.h" 191*e977faadSmarc #include "map.h" /* resource allocation map struct */ 192*e977faadSmarc #include "buf.h" /* buf structs */ 193*e977faadSmarc #include "vm.h" /* includes 'vm' header files */ 194*e977faadSmarc #include "bk.h" /* BKINPUT macro for line stuff */ 195*e977faadSmarc #include "clist.h" /* char list handling structs */ 196*e977faadSmarc #include "file.h" /* file I/O definitions */ 197*e977faadSmarc #include "uio.h" /* write/read call structs */ 198*e977faadSmarc #include "kernel.h" /* clock handling structs */ 199*e977faadSmarc #ifdef notdef /* notneeded */ 200*e977faadSmarc #include "cpuconf.h" 201*e977faadSmarc #include "devio.h" 202*e977faadSmarc #endif 203*e977faadSmarc #include "exec.h" 204*e977faadSmarc #include "proc.h" 20524f67f6bSmarc 206*e977faadSmarc #include "ubareg.h" /* uba & 'qba' register structs */ 207*e977faadSmarc #include "ubavar.h" /* uba structs & uba map externs */ 208*e977faadSmarc #include "syslog.h" 209*e977faadSmarc 210*e977faadSmarc #include "qduser.h" /* definitions shared with my client */ 211*e977faadSmarc #include "qdreg.h" /* QDSS device register structures */ 212*e977faadSmarc /*----------------------------------------------------------- 213*e977faadSmarc * QDSS driver status flags for tracking operational state */ 21424f67f6bSmarc 21524f67f6bSmarc struct qdflags { 21624f67f6bSmarc 21724f67f6bSmarc u_int inuse; /* which minor dev's are in use now */ 21824f67f6bSmarc u_int config; /* I/O page register content */ 21924f67f6bSmarc u_int mapped; /* user mapping status word */ 220*e977faadSmarc u_int kernel_loop; /* if kernel console is redirected */ 22124f67f6bSmarc u_int user_dma; /* DMA from user space in progress */ 22224f67f6bSmarc u_short pntr_id; /* type code of pointing device */ 22324f67f6bSmarc u_short duart_imask; /* shadowing for duart intrpt mask reg */ 22424f67f6bSmarc u_short adder_ie; /* shadowing for adder intrpt enbl reg */ 22524f67f6bSmarc u_short curs_acc; /* cursor acceleration factor */ 22624f67f6bSmarc u_short curs_thr; /* cursor acceleration threshold level */ 22724f67f6bSmarc u_short tab_res; /* tablet resolution factor */ 22824f67f6bSmarc u_short selmask; /* mask for active qd select entries */ 22924f67f6bSmarc }; 23024f67f6bSmarc 231006e9885Smarc /* bit definitions for "inuse" entry */ 232*e977faadSmarc 23324f67f6bSmarc #define CONS_DEV 0x01 23424f67f6bSmarc #define ALTCONS_DEV 0x02 23524f67f6bSmarc #define GRAPHIC_DEV 0x04 23624f67f6bSmarc 23724f67f6bSmarc /* bit definitions for 'mapped' member of flag structure */ 238*e977faadSmarc 23924f67f6bSmarc #define MAPDEV 0x01 /* hardware is mapped */ 24024f67f6bSmarc #define MAPDMA 0x02 /* DMA buffer mapped */ 24124f67f6bSmarc #define MAPEQ 0x04 /* event queue buffer mapped */ 24224f67f6bSmarc #define MAPSCR 0x08 /* scroll param area mapped */ 24324f67f6bSmarc #define MAPCOLOR 0x10 /* color map writing buffer mapped */ 24424f67f6bSmarc 24524f67f6bSmarc /* bit definitions for 'selmask' member of qdflag structure */ 24624f67f6bSmarc 24724f67f6bSmarc #define SEL_READ 0x01 /* read select is active */ 24824f67f6bSmarc #define SEL_WRITE 0x02 /* write select is active */ 24924f67f6bSmarc 250*e977faadSmarc /*---------------------------------------------- 251*e977faadSmarc * constants used in shared memory operations */ 25224f67f6bSmarc 25324f67f6bSmarc #define EVENT_BUFSIZE 1024 /* # of bytes per device's event buffer */ 254*e977faadSmarc 25524f67f6bSmarc #define MAXEVENTS ( (EVENT_BUFSIZE - sizeof(struct qdinput)) \ 25624f67f6bSmarc / sizeof(struct _vs_event) ) 257*e977faadSmarc 2580d59d4d6Smarc #define DMA_BUFSIZ (1024 * 10) 259*e977faadSmarc 26024f67f6bSmarc #define COLOR_BUFSIZ ((sizeof(struct color_buf) + 512) & ~0x01FF) 26124f67f6bSmarc 262*e977faadSmarc /*******************************************************************/ 263*e977faadSmarc 264*e977faadSmarc extern char qvmem[][128*NBPG]; 265*e977faadSmarc extern struct pte QVmap[][128]; 266*e977faadSmarc 267*e977faadSmarc 268*e977faadSmarc /*-------------------------------------------------------------------------- 26924f67f6bSmarc * reference to an array of "uba_device" structures built by the auto 27024f67f6bSmarc * configuration program. The uba_device structure decribes the device 27124f67f6bSmarc * sufficiently for the driver to talk to it. The auto configuration code 27224f67f6bSmarc * fills in the uba_device structures (located in ioconf.c) from user 273*e977faadSmarc * maintained info. */ 27424f67f6bSmarc 27524f67f6bSmarc struct uba_device *qdinfo[NQD]; /* array of pntrs to each QDSS's */ 27624f67f6bSmarc /* uba structures */ 27724f67f6bSmarc struct tty qd_tty[NQD*4]; /* teletype structures for each.. */ 27824f67f6bSmarc /* ..possible minor device */ 27924f67f6bSmarc 28024f67f6bSmarc struct qd_softc qd_softc[NQD]; 28124f67f6bSmarc 282*e977faadSmarc /*---------------------------------------------------------- 283*e977faadSmarc * static storage used by multiple functions in this code */ 284*e977faadSmarc 28524f67f6bSmarc int Qbus_unmap[NQD]; /* Qbus mapper release code */ 28624f67f6bSmarc struct qdflags qdflags[NQD]; /* QDSS device status flags */ 28724f67f6bSmarc struct qdmap qdmap[NQD]; /* QDSS register map structure */ 28824f67f6bSmarc caddr_t qdbase[NQD]; /* base address of each QDSS unit */ 28924f67f6bSmarc struct buf qdbuf[NQD]; /* buf structs used by strategy */ 29024f67f6bSmarc char one_only[NQD]; /* lock for single process access */ 29124f67f6bSmarc 292*e977faadSmarc /*------------------------------------------------------------------------ 293*e977faadSmarc * the array "event_shared[]" is made up of a number of event queue buffers 29424f67f6bSmarc * equal to the number of QDSS's configured into the running kernel (NQD). 29524f67f6bSmarc * Each event queue buffer begins with an event queue header (struct qdinput) 29624f67f6bSmarc * followed by a group of event queue entries (struct _vs_event). The array 29724f67f6bSmarc * "*eq_header[]" is an array of pointers to the start of each event queue 298*e977faadSmarc * buffer in "event_shared[]". */ 29924f67f6bSmarc 30024f67f6bSmarc #define EQSIZE ((EVENT_BUFSIZE * NQD) + 512) 30124f67f6bSmarc 30224f67f6bSmarc char event_shared[EQSIZE]; /* reserve space for event bufs */ 30324f67f6bSmarc struct qdinput *eq_header[NQD]; /* event queue header pntrs */ 30424f67f6bSmarc 305*e977faadSmarc /*-------------------------------------------------------------------------- 30624f67f6bSmarc * This allocation method reserves enough memory pages for NQD shared DMA I/O 30724f67f6bSmarc * buffers. Each buffer must consume an integral number of memory pages to 30824f67f6bSmarc * guarantee that a following buffer will begin on a page boundary. Also, 30924f67f6bSmarc * enough space is allocated so that the FIRST I/O buffer can start at the 31024f67f6bSmarc * 1st page boundary after "&DMA_shared". Page boundaries are used so that 311*e977faadSmarc * memory protections can be turned on/off for individual buffers. */ 31224f67f6bSmarc 31324f67f6bSmarc #define IOBUFSIZE ((DMA_BUFSIZ * NQD) + 512) 31424f67f6bSmarc 31524f67f6bSmarc char DMA_shared[IOBUFSIZE]; /* reserve I/O buffer space */ 31624f67f6bSmarc struct DMAreq_header *DMAheader[NQD]; /* DMA buffer header pntrs */ 31724f67f6bSmarc 318*e977faadSmarc /*------------------------------------------------------------------------- 31924f67f6bSmarc * The driver assists a client in scroll operations by loading dragon 32024f67f6bSmarc * registers from an interrupt service routine. The loading is done using 32124f67f6bSmarc * parameters found in memory shrade between the driver and it's client. 32224f67f6bSmarc * The scroll parameter structures are ALL loacted in the same memory page 323*e977faadSmarc * for reasons of memory economy. */ 32424f67f6bSmarc 32524f67f6bSmarc char scroll_shared[2 * 512]; /* reserve space for scroll structs */ 32624f67f6bSmarc struct scroll *scroll[NQD]; /* pointers to scroll structures */ 32724f67f6bSmarc 328*e977faadSmarc /*----------------------------------------------------------------------- 32924f67f6bSmarc * the driver is programmable to provide the user with color map write 33024f67f6bSmarc * services at VSYNC interrupt time. At interrupt time the driver loads 331*e977faadSmarc * the color map with any user-requested load data found in shared memory */ 33224f67f6bSmarc 33324f67f6bSmarc #define COLOR_SHARED ((COLOR_BUFSIZ * NQD) + 512) 33424f67f6bSmarc 335*e977faadSmarc char color_shared[COLOR_SHARED]; /* reserve space: color bufs */ 33624f67f6bSmarc struct color_buf *color_buf[NQD]; /* pointers to color bufs */ 33724f67f6bSmarc 338*e977faadSmarc /*-------------------------------- 339*e977faadSmarc * mouse input event structures */ 34024f67f6bSmarc 34124f67f6bSmarc struct mouse_report last_rep[NQD]; 34224f67f6bSmarc struct mouse_report current_rep[NQD]; 34324f67f6bSmarc 344*e977faadSmarc /*---------------------------- 345*e977faadSmarc * input event "select" use */ 34624f67f6bSmarc 34724f67f6bSmarc struct proc *rsel[NQD]; /* process waiting for select */ 34824f67f6bSmarc 349*e977faadSmarc /*---------------------------- 350*e977faadSmarc * console cursor structure */ 35124f67f6bSmarc 35224f67f6bSmarc struct _vs_cursor cursor[NQD]; 35324f67f6bSmarc 354*e977faadSmarc /*---------------------------- 355*e977faadSmarc * count of successfully probed qd's */ 35624f67f6bSmarc 357*e977faadSmarc int qdcount = 0; 358*e977faadSmarc 359*e977faadSmarc 360*e977faadSmarc /************************************************************************/ 36124f67f6bSmarc 36224f67f6bSmarc int nNQD = NQD; 36324f67f6bSmarc 36424f67f6bSmarc int DMAbuf_size = DMA_BUFSIZ; 36524f67f6bSmarc 36624f67f6bSmarc 367*e977faadSmarc #define QDSSMAJOR 41 /* QDSS major device number */ 368*e977faadSmarc #ifdef notdef /* on ultrix */ 369*e977faadSmarc extern int ws_display_type; 370*e977faadSmarc extern int ws_display_units; 371*e977faadSmarc #endif 372*e977faadSmarc /* don't need these */ 373*e977faadSmarc int ws_display_type; 374*e977faadSmarc int ws_display_units; 375*e977faadSmarc 376*e977faadSmarc int QDlast_DMAtype; /* type of the last DMA operation */ 377*e977faadSmarc 378*e977faadSmarc /*--------------------------------------------------------------------- 379*e977faadSmarc * macro to get system time. Used to time stamp event queue entries */ 3807e911b15Skarels 3817e911b15Skarels #define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000)) 3827e911b15Skarels 383*e977faadSmarc /*-------------------------------------------------------------------------- 3847e911b15Skarels * the "ioconf.c" program, built and used by auto config, externally refers 385*e977faadSmarc * to definitions below. */ 3867e911b15Skarels 3877e911b15Skarels int qdprobe(); 3887e911b15Skarels int qdattach(); 3897e911b15Skarels int qddint(); /* DMA gate array intrpt service */ 3907e911b15Skarels int qdaint(); /* Dragon ADDER intrpt service */ 3917e911b15Skarels int qdiint(); 3927e911b15Skarels 3937e911b15Skarels u_short qdstd[] = { 0 }; 3947e911b15Skarels 3957e911b15Skarels struct uba_driver qddriver = { /* externally referenced: ioconf.c */ 3967e911b15Skarels 3977e911b15Skarels qdprobe, /* device probe entry */ 3987e911b15Skarels 0, /* no slave device */ 3997e911b15Skarels qdattach, /* device attach entry */ 4007e911b15Skarels 0, /* no "fill csr/ba to start" */ 4017e911b15Skarels qdstd, /* device addresses */ 4027e911b15Skarels "qd", /* device name string */ 4037e911b15Skarels qdinfo /* ptr to QDSS's uba_device struct */ 4047e911b15Skarels }; 4057e911b15Skarels 406*e977faadSmarc /*------------------- 4077e911b15Skarels * general defines */ 4087e911b15Skarels 409*e977faadSmarc #define QDPRIOR (PZERO-1) /* must be negative */ 4107e911b15Skarels 4117e911b15Skarels #define FALSE 0 4127e911b15Skarels #define TRUE ~FALSE 4137e911b15Skarels 4147e911b15Skarels #define BAD -1 4157e911b15Skarels #define GOOD 0 4167e911b15Skarels 417*e977faadSmarc /*----------------------------------------------------------------------- 418*e977faadSmarc * macro to create a system virtual page number from system virtual adrs */ 4197e911b15Skarels 420*e977faadSmarc #define VTOP(x) (((int)x & ~0xC0000000) >> PGSHIFT) /* convert qvmem adrs */ 421*e977faadSmarc /* to system page # */ 4227e911b15Skarels 423*e977faadSmarc /*------------------------------------------------------------------ 424*e977faadSmarc * QDSS register address offsets from start of QDSS address space */ 4257e911b15Skarels 4267e911b15Skarels #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ 4277e911b15Skarels 4287e911b15Skarels #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ 4297e911b15Skarels #define TMPSTART 0x8000 /* offset of template RAM from base adrs */ 4307e911b15Skarels 4317e911b15Skarels #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ 4327e911b15Skarels #define REGSTART 0xC000 /* offset of reg pages from base adrs */ 4337e911b15Skarels 4347e911b15Skarels #define ADDER (REGSTART+0x000) 4357e911b15Skarels #define DGA (REGSTART+0x200) 4367e911b15Skarels #define DUART (REGSTART+0x400) 4377e911b15Skarels #define MEMCSR (REGSTART+0x800) 4387e911b15Skarels 4397e911b15Skarels #define CLRSIZE (3 * 512) /* color map size */ 4407e911b15Skarels #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ 4417e911b15Skarels /* 0x0C00 really */ 4427e911b15Skarels #define RED (CLRSTART+0x000) 4437e911b15Skarels #define BLUE (CLRSTART+0x200) 4447e911b15Skarels #define GREEN (CLRSTART+0x400) 4457e911b15Skarels 446*e977faadSmarc /*--------------------------------------------------------------- 447*e977faadSmarc * values used in mapping QDSS hardware into the Q memory space */ 4487e911b15Skarels 4497e911b15Skarels #define CHUNK (64 * 1024) 450*e977faadSmarc #define QMEMSIZE (1024 * 1024 * 4) /* 4 meg */ 4517e911b15Skarels 452*e977faadSmarc /*---------------------------------------------------------------------- 4537e911b15Skarels * QDSS minor device numbers. The *real* minor device numbers are in 4547e911b15Skarels * the bottom two bits of the major/minor device spec. Bits 2 and up are 455*e977faadSmarc * used to specify the QDSS device number (ie: which one?) */ 4567e911b15Skarels 4577e911b15Skarels 4587e911b15Skarels #define CONS 0 4597e911b15Skarels #define ALTCONS 1 4607e911b15Skarels #define GRAPHIC 2 4617e911b15Skarels 462*e977faadSmarc /*---------------------------------------------- 463*e977faadSmarc * console cursor bitmap (block cursor type) */ 4647e911b15Skarels 4657e911b15Skarels short cons_cursor[32] = { /* white block cursor */ 4667e911b15Skarels 4677e911b15Skarels /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 4687e911b15Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 4697e911b15Skarels /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 4707e911b15Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 4717e911b15Skarels 4727e911b15Skarels }; 4737e911b15Skarels 474*e977faadSmarc /*------------------------------------- 475*e977faadSmarc * constants used in font operations */ 4767e911b15Skarels 477*e977faadSmarc 478*e977faadSmarc /* Originaly this was CHARS 95 */ 479*e977faadSmarc #define CHARS 190 /* # of chars in the font */ 480*e977faadSmarc 4817e911b15Skarels #define CHAR_HEIGHT 15 /* char height in pixels */ 4827e911b15Skarels #define CHAR_WIDTH 8 /* char width in pixels*/ 4837e911b15Skarels #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ 4847e911b15Skarels #define ROWS CHAR_HEIGHT 4857e911b15Skarels 4867e911b15Skarels 4877e911b15Skarels #define FONT_X 0 /* font's off screen adrs */ 4887e911b15Skarels #define FONT_Y (2048 - CHAR_HEIGHT) 489*e977faadSmarc 490*e977faadSmarc /* Offset to second row characters */ 491*e977faadSmarc #define FONT_OFFSET ((MAX_SCREEN_X/CHAR_WIDTH)*CHAR_HEIGHT) 4927e911b15Skarels 4937e911b15Skarels extern char q_font[]; /* reference font object code */ 4947e911b15Skarels 495*e977faadSmarc extern u_short q_key[]; /* reference key xlation tables */ 496*e977faadSmarc extern u_short q_shift_key[]; 4977e911b15Skarels extern char *q_special[]; 4987e911b15Skarels 499*e977faadSmarc /*-------------------------------------------------- 500*e977faadSmarc * definitions for cursor acceleration reporting */ 5017e911b15Skarels 5027e911b15Skarels #define ACC_OFF 0x01 /* acceleration is inactive */ 5037e911b15Skarels 504*e977faadSmarc /*-------------------------------------------------------------------------- 505*e977faadSmarc * v_consputc is the switch that is used to redirect the console cnputc() to 506*e977faadSmarc * the virtual console qdputc(). 507*e977faadSmarc * v_consgetc is the switch that is used to redirect the console getchar() to 508*e977faadSmarc * the virtual console qdgetc(). 5097e911b15Skarels */ 5107e911b15Skarels 511*e977faadSmarc #ifdef notdef 512*e977faadSmarc extern (*v_consputc)(); 513*e977faadSmarc int qdputc(); /* used to direct kernel console output */ 514*e977faadSmarc extern (*v_consgetc)(); 515*e977faadSmarc int qdgetc(); /* used to read kernel console input */ 516*e977faadSmarc 517*e977faadSmarc int qdstart(); /* used to direct /dev/console output */ 518*e977faadSmarc #endif 519*e977faadSmarc extern (*v_putc)(); 520*e977faadSmarc extern struct cdevsw *consops; 521*e977faadSmarc int qdputc(); 522*e977faadSmarc int qdstart(); 523*e977faadSmarc 524*e977faadSmarc /*------------------------------------------------------------------------ 525*e977faadSmarc * LK-201 state storage for input console keyboard conversion to ASCII */ 526*e977faadSmarc 5277e911b15Skarels struct q_keyboard { 528*e977faadSmarc 5297e911b15Skarels int shift; /* state variables */ 5307e911b15Skarels int cntrl; 5317e911b15Skarels int lock; 5327e911b15Skarels int lastcode; /* last keycode typed */ 5337e911b15Skarels unsigned kup[8]; /* bits for each keycode*/ 5347e911b15Skarels unsigned dkeys[8]; /* down/up mode keys */ 5357e911b15Skarels char last; /* last character */ 536*e977faadSmarc 5377e911b15Skarels } q_keyboard; 5387e911b15Skarels 539*e977faadSmarc /*-------------------------------------------------- 540*e977faadSmarc * ULTRIX settings for first open. */ 541*e977faadSmarc 542*e977faadSmarc #define IFLAGS (EVENP|ECHO|XTABS|CRMOD) 543*e977faadSmarc 544*e977faadSmarc /*------------------------------------------------------------------------ 545*e977faadSmarc * termio flags will be set to these default values in non-termio mode to 546*e977faadSmarc * provide a backward compatible ULTRIX environment. */ 547*e977faadSmarc 548*e977faadSmarc #ifdef POSIXTTY 549*e977faadSmarc #define IFLAG (BRKINT|ISTRIP|IXON|IXANY|ICRNL|IEXTEN|IMAXBEL) 550*e977faadSmarc #define OFLAG (OPOST|OXTABS|ONLCR) 551*e977faadSmarc #define LFLAG (ISIG|ICANON|ECHO) 552*e977faadSmarc #define CFLAG (PARENB|CREAD|CS7|CLOCAL) 553*e977faadSmarc #endif 554*e977faadSmarc 555*e977faadSmarc /***************************************************************** 556*e977faadSmarc ****************************************************************** 557*e977faadSmarc ****************************************************************** 558*e977faadSmarc * 559*e977faadSmarc * DRIVER FUNCTIONS START HERE: 560*e977faadSmarc * 561*e977faadSmarc ****************************************************************** 562*e977faadSmarc ****************************************************************** 563*e977faadSmarc *****************************************************************/ 5647e911b15Skarels 5657e911b15Skarels /********************************************************************* 5667e911b15Skarels * 567*e977faadSmarc * qdcons_init()... init QDSS as console (before probe routine) 5687e911b15Skarels * 5697e911b15Skarels *********************************************************************/ 5707e911b15Skarels 5717e911b15Skarels qdcons_init() 5727e911b15Skarels { 5737e911b15Skarels register u_int unit; 5747e911b15Skarels 5757e911b15Skarels int *ptep; /* page table entry pointer */ 5767e911b15Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 577*e977faadSmarc u_int mapix; /* index into QVmap[] array */ 5787e911b15Skarels 579*e977faadSmarc struct percpu *pcpu; /* pointer to cpusw structure */ 580*e977faadSmarc register struct qbus *qb; 5817e911b15Skarels u_short *qdaddr; /* address of QDSS IO page CSR */ 5827e911b15Skarels u_short *devptr; /* vitual device space */ 583*e977faadSmarc extern cnputc(); 5847e911b15Skarels 5857e911b15Skarels #define QDSSCSR 0x1F00 5867e911b15Skarels 58724f67f6bSmarc if (v_putc != cnputc) 58824f67f6bSmarc return; 58924f67f6bSmarc 5907e911b15Skarels unit = 0; 5917e911b15Skarels 592*e977faadSmarc /*---------------------------------------------------- 593*e977faadSmarc * find the cpusw entry that matches this machine. */ 5947e911b15Skarels 59524f67f6bSmarc for (pcpu = percpu; pcpu && pcpu->pc_cputype != cpu; pcpu++) 5967e911b15Skarels ; 59724f67f6bSmarc if (pcpu == NULL) 59824f67f6bSmarc return; 59924f67f6bSmarc 600*e977faadSmarc #ifdef notdef /* the ultrix way */ 601*e977faadSmarc /*------------------------------------------------------ 602*e977faadSmarc * Map the Q-bus memory space into the system memory. */ 60324f67f6bSmarc 604*e977faadSmarc ubaaccess(((*cpup->v_umaddr)(0)), QVmap[0], 605*e977faadSmarc cpup->pc_umsize, PG_V | PG_KW); 606*e977faadSmarc 607*e977faadSmarc ubaaccess(((*cpup->v_udevaddr)(0)), QVmap[0]+btop(cpup->pc_umsize), 608*e977faadSmarc DEVSPACESIZE ,PG_V|PG_KW); 609*e977faadSmarc 610*e977faadSmarc /*--------------------------------------------------------------------- 611*e977faadSmarc * map the QDSS into the Qbus memory (which is now in system space) */ 612*e977faadSmarc 613*e977faadSmarc devptr = (u_short *)((char *)qvmem[0]+cpup->pc_umsize); 614*e977faadSmarc qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 615*e977faadSmarc 616*e977faadSmarc if (BADADDR(qdaddr, sizeof(short))) 617*e977faadSmarc return(0); 618*e977faadSmarc 619*e977faadSmarc /*--------------------------------------------------- 620*e977faadSmarc * tell QDSS which Q memory address base to decode */ 621*e977faadSmarc 622*e977faadSmarc mapix = (int) VTOP(QMEMSIZE - CHUNK); 623*e977faadSmarc ptep = (int *) QVmap[0] + mapix; 624*e977faadSmarc phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 625*e977faadSmarc *qdaddr = (u_short) ((int)phys_adr >> 16); 626*e977faadSmarc 627*e977faadSmarc qdflags[unit].config = *(u_short *)qdaddr; 628*e977faadSmarc 629*e977faadSmarc #endif /*notdef*/ 630*e977faadSmarc 631*e977faadSmarc /* the BSD way */ 63224f67f6bSmarc /* 633*e977faadSmarc * Map device registers - the last 8K of qvmem. 63424f67f6bSmarc */ 63524f67f6bSmarc qb = (struct qbus *)pcpu->pc_io->io_details; 63624f67f6bSmarc ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize, 63724f67f6bSmarc UBAIOPAGES * NBPG); 63824f67f6bSmarc 63924f67f6bSmarc devptr = (u_short *)((char *)umem[0]+(qb->qb_memsize * NBPG)); 64024f67f6bSmarc qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 64124f67f6bSmarc if (badaddr(qdaddr, sizeof(short))) { 642*e977faadSmarc printf("Can't find qdss (badaddr)\n"); /* debug */ 6437e911b15Skarels return(0); 6447e911b15Skarels } 645*e977faadSmarc 646*e977faadSmarc 647*e977faadSmarc 64824f67f6bSmarc /* 64924f67f6bSmarc * Map q-bus memory used by qdss. (separate map) 65024f67f6bSmarc */ 65124f67f6bSmarc mapix = QMEMSIZE - (CHUNK * (unit + 1)); 65224f67f6bSmarc phys_adr = qb->qb_maddr + mapix; 65324f67f6bSmarc ioaccess(phys_adr, QVmap[0], (CHUNK*NQD)); 6547e911b15Skarels 65524f67f6bSmarc /* 65624f67f6bSmarc * tell QDSS which Q memory address base to decode 65724f67f6bSmarc */ 6587e911b15Skarels 65924f67f6bSmarc /* 66024f67f6bSmarc * shifted right 16 bits - its in 64K units 66124f67f6bSmarc */ 66224f67f6bSmarc *qdaddr = (u_short)((int)mapix >> 16); 6637e911b15Skarels qdflags[unit].config = *(u_short *)qdaddr; 6647e911b15Skarels 665*e977faadSmarc /*---------------------------------------------------------------------- 666*e977faadSmarc * load qdmap struct with the virtual addresses of the QDSS elements */ 6677e911b15Skarels 668*e977faadSmarc #ifdef notdef /*ultrix way */ 669*e977faadSmarc qdbase[unit] = (caddr_t) (qvmem[0] + QMEMSIZE - CHUNK); 670*e977faadSmarc #endif 671*e977faadSmarc 672*e977faadSmarc qdbase[unit] = (caddr_t) (qvmem[0]); 6737e911b15Skarels 6747e911b15Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 6757e911b15Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 6767e911b15Skarels qdmap[unit].dga = qdbase[unit] + DGA; 6777e911b15Skarels qdmap[unit].duart = qdbase[unit] + DUART; 6787e911b15Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 6797e911b15Skarels qdmap[unit].red = qdbase[unit] + RED; 6807e911b15Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 6817e911b15Skarels qdmap[unit].green = qdbase[unit] + GREEN; 6827e911b15Skarels 6837e911b15Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 6847e911b15Skarels 685*e977faadSmarc /*------------------ 686*e977faadSmarc * init the QDSS */ 68724f67f6bSmarc 68824f67f6bSmarc printf("qdbase[0] = %x, qdmap[0].memcsr = %x\n", 68924f67f6bSmarc (char *)qdbase[0], qdmap[0].memcsr); 6907e911b15Skarels 6917e911b15Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */ 6927e911b15Skarels 6937e911b15Skarels cursor[unit].x = 0; 6947e911b15Skarels cursor[unit].y = 0; 6957e911b15Skarels init_shared(unit); /* init shared memory */ 6967e911b15Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 6977e911b15Skarels clear_qd_screen(unit); /* clear the screen */ 6987e911b15Skarels ldfont(unit); /* load the console font */ 6997e911b15Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 7007e911b15Skarels setup_input(unit); /* init the DUART */ 7017e911b15Skarels 702*e977faadSmarc /*---------------------------------------------------- 703*e977faadSmarc * smash the system's virtual console address table */ 704*e977faadSmarc 705*e977faadSmarc #ifdef notdef /* the ultrix way */ 706*e977faadSmarc v_consputc = qdputc; 707*e977faadSmarc v_consgetc = qdgetc; 708*e977faadSmarc cdevsw[0] = cdevsw[QDSSMAJOR]; 709*e977faadSmarc #endif 710*e977faadSmarc /* the bsd way */ 71124f67f6bSmarc v_putc = qdputc; 71224f67f6bSmarc consops = &cdevsw[QDSSMAJOR]; 7137e911b15Skarels 714*e977faadSmarc ws_display_type = QDSSMAJOR; /* Idenify QDSS as graphics device */ 7157e911b15Skarels return(1); 7167e911b15Skarels 7177e911b15Skarels } /* qdcons_init */ 7187e911b15Skarels 7197e911b15Skarels /********************************************************************* 7207e911b15Skarels * 7217e911b15Skarels * qdprobe()... configure QDSS into Q memory and make it intrpt 7227e911b15Skarels * 7237e911b15Skarels ********************************************************************** 7247e911b15Skarels * 7257e911b15Skarels * calling convention: 7267e911b15Skarels * qdprobe(reg, ctlr); 7277e911b15Skarels * caddr_t reg; 7287e911b15Skarels * int ctlr; 7297e911b15Skarels * 7307e911b15Skarels * where: reg - a character pointer to the QDSS I/O page register 7317e911b15Skarels * ctlr - controller number (?) 7327e911b15Skarels * 7337e911b15Skarels * side effects: QDSS gets mapped into Qbus memory space at the first 7347e911b15Skarels * vacant 64kb boundary counting back from the top of 735*e977faadSmarc * Qbus memory space (qvmem+4mb) 7367e911b15Skarels * 7377e911b15Skarels * return: QDSS bus request level and vector address returned in 7387e911b15Skarels * registers by UNIX convention. 7397e911b15Skarels * 7407e911b15Skarels *****************/ 7417e911b15Skarels 7427e911b15Skarels qdprobe(reg) 7437e911b15Skarels caddr_t reg; 7447e911b15Skarels { 74524f67f6bSmarc register int br, cvec; /* value-result */ 7467e911b15Skarels 7477e911b15Skarels register int unit; 7487e911b15Skarels 7497e911b15Skarels struct dga *dga; /* pointer to gate array structure */ 7507e911b15Skarels struct cpusw *cpup; /* pointer to the cpusw structure */ 7517e911b15Skarels 7527e911b15Skarels int *ptep; /* page table entry pointer */ 7537e911b15Skarels int vector; 7547e911b15Skarels 7557e911b15Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 7567e911b15Skarels u_int mapix; 7577e911b15Skarels 758*e977faadSmarc /*--------------------------------------------------------------- 759*e977faadSmarc * calculate board unit number from I/O page register address */ 7607e911b15Skarels 7617e911b15Skarels unit = (int) (((int)reg >> 1) & 0x0007); 7627e911b15Skarels 763*e977faadSmarc /*--------------------------------------------------------------------------- 7647e911b15Skarels * QDSS regs must be mapped to Qbus memory space at a 64kb physical boundary. 7657e911b15Skarels * The Qbus memory space is mapped into the system memory space at config 766*e977faadSmarc * time. After config runs, "qvmem[0]" (ubavar.h) holds the system virtual adrs 7677e911b15Skarels * of the start of Qbus memory. The Qbus memory page table is found via 768*e977faadSmarc * an array of pte ptrs called "QVmap[]" (ubavar.h) which is also loaded at 7697e911b15Skarels * config time. These are the variables used below to find a vacant 64kb 7707e911b15Skarels * boundary in Qbus memory, and load it's corresponding physical adrs into 771*e977faadSmarc * the QDSS's I/O page CSR. */ 772*e977faadSmarc 773*e977faadSmarc /* 774*e977faadSmarc * Only if QD is the graphics device. 77524f67f6bSmarc */ 7767e911b15Skarels 777*e977faadSmarc if (ws_display_type && (ws_display_type != QDSSMAJOR)) 778*e977faadSmarc return(0); 779*e977faadSmarc 7807e911b15Skarels /* if this QDSS is NOT the console, then do init here.. */ 7817e911b15Skarels 782*e977faadSmarc if (unit != 0) { 783*e977faadSmarc printf("qd: can't support two qdss's (yet)\n"); 784*e977faadSmarc #ifdef notdef /* notyet */ 7857e911b15Skarels if (v_consputc != qdputc || unit != 0) { 7867e911b15Skarels 787*e977faadSmarc /*------------------------- 788*e977faadSmarc * read QDSS config info */ 789*e977faadSmarc 7907e911b15Skarels qdflags[unit].config = *(u_short *)reg; 7917e911b15Skarels 792*e977faadSmarc /*------------------------------------ 793*e977faadSmarc * find an empty 64kb adrs boundary */ 7947e911b15Skarels 795*e977faadSmarc qdbase[unit] = (caddr_t) (qvmem[0] + QMEMSIZE - CHUNK); 796*e977faadSmarc 797*e977faadSmarc /*---------------------------------------------------- 798*e977faadSmarc * find the cpusw entry that matches this machine. */ 799*e977faadSmarc 8007e911b15Skarels cpup = &cpusw[cpu]; 8017e911b15Skarels while ( !(BADADDR(qdbase[unit], sizeof(short))) ) 8027e911b15Skarels qdbase[unit] -= CHUNK; 8037e911b15Skarels 804*e977faadSmarc /*--------------------------------------------------- 805*e977faadSmarc * tell QDSS which Q memory address base to decode */ 806*e977faadSmarc 807*e977faadSmarc mapix = (int) (VTOP(qdbase[unit]) - VTOP(qvmem[0])); 808*e977faadSmarc ptep = (int *) QVmap[0] + mapix; 8097e911b15Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 8107e911b15Skarels *(u_short *)reg = (u_short) ((int)phys_adr >> 16); 8117e911b15Skarels 812*e977faadSmarc /*----------------------------------------------------------- 813*e977faadSmarc * load QDSS adrs map with system addresses of device regs */ 814*e977faadSmarc 8157e911b15Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 8167e911b15Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 8177e911b15Skarels qdmap[unit].dga = qdbase[unit] + DGA; 8187e911b15Skarels qdmap[unit].duart = qdbase[unit] + DUART; 8197e911b15Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 8207e911b15Skarels qdmap[unit].red = qdbase[unit] + RED; 8217e911b15Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 8227e911b15Skarels qdmap[unit].green = qdbase[unit] + GREEN; 8237e911b15Skarels 8247e911b15Skarels /* device init */ 8257e911b15Skarels 8267e911b15Skarels cursor[unit].x = 0; 8277e911b15Skarels cursor[unit].y = 0; 8287e911b15Skarels init_shared(unit); /* init shared memory */ 8297e911b15Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 8307e911b15Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 8317e911b15Skarels setup_input(unit); /* init the DUART */ 8327e911b15Skarels clear_qd_screen(unit); 8337e911b15Skarels ldfont(unit); /* load the console font */ 8347e911b15Skarels 8357e911b15Skarels /* once only: turn on sync */ 8367e911b15Skarels 8377e911b15Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; 838006e9885Smarc #endif /*notdef*/ 839*e977faadSmarc } 8407e911b15Skarels 841*e977faadSmarc /*-------------------------------------------------------------------------- 8427e911b15Skarels * the QDSS interrupts at HEX vectors xx0 (DMA) xx4 (ADDER) and xx8 (DUART). 8437e911b15Skarels * Therefore, we take three vectors from the vector pool, and then continue 8447e911b15Skarels * to take them until we get a xx0 HEX vector. The pool provides vectors 845*e977faadSmarc * in contiguous decending order. */ 8467e911b15Skarels 8477e911b15Skarels vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ 8487e911b15Skarels 8497e911b15Skarels while (vector & 0x0F) { /* if lo nibble != 0.. */ 8507e911b15Skarels vector = (uba_hd[0].uh_lastiv -= 4); /* ..take another vector */ 8517e911b15Skarels } 8527e911b15Skarels 853*e977faadSmarc /*--------------------------------------------------------- 854*e977faadSmarc * setup DGA to do a DMA interrupt (transfer count = 0) */ 8557e911b15Skarels 8567e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 8577e911b15Skarels 8587e911b15Skarels dga->csr = (short) HALT; /* disable everything */ 8597e911b15Skarels dga->ivr = (short) vector; /* load intrpt base vector */ 8607e911b15Skarels dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ 8617e911b15Skarels dga->bytcnt_hi = (short) 0; 8627e911b15Skarels 8637e911b15Skarels /* turn on DMA interrupts */ 8647e911b15Skarels 8657e911b15Skarels dga->csr &= ~SET_DONE_FIFO; 8667e911b15Skarels dga->csr |= DMA_IE | DL_ENB; 8677e911b15Skarels 8687e911b15Skarels DELAY(20000); /* wait for the intrpt */ 8697e911b15Skarels 8707e911b15Skarels dga->csr = HALT; /* stop the wheels */ 8717e911b15Skarels 872*e977faadSmarc /*---------- 873*e977faadSmarc * exits */ 874*e977faadSmarc 8757e911b15Skarels if (cvec != vector) /* if vector != base vector.. */ 8767e911b15Skarels return(0); /* ..return = 'no device' */ 8777e911b15Skarels 878*e977faadSmarc /* 879*e977faadSmarc * score this as an existing qdss 880*e977faadSmarc */ 881*e977faadSmarc qdcount++; 882*e977faadSmarc ws_display_units |= (1 << unit); 883*e977faadSmarc 8847e911b15Skarels return(sizeof(short)); /* return size of QDSS I/O page reg */ 8857e911b15Skarels 8867e911b15Skarels } /* qdprobe */ 8877e911b15Skarels 8887e911b15Skarels /***************************************************************** 8897e911b15Skarels * 890*e977faadSmarc * qdattach()... do the one-time initialization 8917e911b15Skarels * 8927e911b15Skarels ****************************************************************** 8937e911b15Skarels * 8947e911b15Skarels * calling convention: 8957e911b15Skarels * qdattach(ui); 8967e911b15Skarels * struct uba_device *ui; 8977e911b15Skarels * 8987e911b15Skarels * where: ui - pointer to the QDSS's uba_device structure 8997e911b15Skarels * 9007e911b15Skarels * side effects: none 9017e911b15Skarels * return: none 9027e911b15Skarels * 9037e911b15Skarels *************************/ 9047e911b15Skarels 9057e911b15Skarels qdattach(ui) 9067e911b15Skarels struct uba_device *ui; 9077e911b15Skarels { 9087e911b15Skarels register u_int unit; /* QDSS module # for this call */ 9097e911b15Skarels 9107e911b15Skarels unit = ui->ui_unit; /* get QDSS number */ 9117e911b15Skarels 912*e977faadSmarc /*---------------------------------- 913*e977faadSmarc * init "qdflags[]" for this QDSS */ 9147e911b15Skarels 9157e911b15Skarels qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ 9167e911b15Skarels qdflags[unit].mapped = 0; 917*e977faadSmarc qdflags[unit].kernel_loop = -1; 9187e911b15Skarels qdflags[unit].user_dma = 0; 9197e911b15Skarels qdflags[unit].curs_acc = ACC_OFF; 9207e911b15Skarels qdflags[unit].curs_thr = 128; 9217e911b15Skarels qdflags[unit].tab_res = 2; /* default tablet resolution factor */ 9227e911b15Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 9237e911b15Skarels qdflags[unit].adder_ie = 0; 9247e911b15Skarels 925*e977faadSmarc /*---------------------------------------------------------------------- 9267e911b15Skarels * init structures used in kbd/mouse interrupt service. This code must 927*e977faadSmarc * come after the "init_shared()" routine has run since that routine inits 928*e977faadSmarc * the eq_header[unit] structure used here. */ 9297e911b15Skarels 930*e977faadSmarc /*-------------------------------------------- 931*e977faadSmarc * init the "latest mouse report" structure */ 9327e911b15Skarels 9337e911b15Skarels last_rep[unit].state = 0; 9347e911b15Skarels last_rep[unit].dx = 0; 9357e911b15Skarels last_rep[unit].dy = 0; 9367e911b15Skarels last_rep[unit].bytcnt = 0; 9377e911b15Skarels 938*e977faadSmarc /*------------------------------------------------ 939*e977faadSmarc * init the event queue (except mouse position) */ 9407e911b15Skarels 9417e911b15Skarels eq_header[unit]->header.events = (struct _vs_event *) 9427e911b15Skarels ((int)eq_header[unit] 9437e911b15Skarels + sizeof(struct qdinput)); 9447e911b15Skarels 9457e911b15Skarels eq_header[unit]->header.size = MAXEVENTS; 9467e911b15Skarels eq_header[unit]->header.head = 0; 9477e911b15Skarels eq_header[unit]->header.tail = 0; 9487e911b15Skarels 949*e977faadSmarc /*------------------------------------------ 950*e977faadSmarc * init single process access lock switch */ 9517e911b15Skarels 9527e911b15Skarels one_only[unit] = 0; 9537e911b15Skarels 9547e911b15Skarels } /* qdattach */ 9557e911b15Skarels 9567e911b15Skarels /*************************************************************** 9577e911b15Skarels * 958*e977faadSmarc * qdopen()... open a minor device 9597e911b15Skarels * 9607e911b15Skarels **************************************************************** 9617e911b15Skarels * 9627e911b15Skarels * calling convention: qdopen(dev, flag); 9637e911b15Skarels * dev_t dev; 9647e911b15Skarels * int flag; 9657e911b15Skarels * 9667e911b15Skarels * side effects: none 9677e911b15Skarels * 9687e911b15Skarels *********************/ 9697e911b15Skarels 9707e911b15Skarels qdopen(dev, flag) 9717e911b15Skarels dev_t dev; 9727e911b15Skarels int flag; 9737e911b15Skarels { 9747e911b15Skarels register struct uba_device *ui; /* ptr to uba structures */ 9757e911b15Skarels register struct dga *dga; /* ptr to gate array struct */ 9767e911b15Skarels register struct tty *tp; 9777e911b15Skarels 9787e911b15Skarels struct adder *adder; 9797e911b15Skarels struct duart *duart; 9807e911b15Skarels 9817e911b15Skarels u_int unit; 9827e911b15Skarels u_int minor_dev; 9837e911b15Skarels int s; 9847e911b15Skarels 9857e911b15Skarels minor_dev = minor(dev); /* get QDSS minor device number */ 9867e911b15Skarels unit = minor_dev >> 2; 9877e911b15Skarels 988*e977faadSmarc /*--------------------------------- 989*e977faadSmarc * check for illegal conditions */ 9907e911b15Skarels 9917e911b15Skarels ui = qdinfo[unit]; /* get ptr to QDSS device struct */ 9927e911b15Skarels 9937e911b15Skarels if (ui == 0 || ui->ui_alive == 0) 9947e911b15Skarels return(ENXIO); /* no such device or address */ 9957e911b15Skarels 996*e977faadSmarc /*-------------- 997*e977faadSmarc * init stuff */ 9987e911b15Skarels 9997e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 10007e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 10017e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 10027e911b15Skarels 1003*e977faadSmarc /*------------------------------------ 1004*e977faadSmarc * if this is the graphic device... */ 10057e911b15Skarels 10067e911b15Skarels if ((minor_dev & 0x03) == 2) { 10077e911b15Skarels 10087e911b15Skarels if (one_only[unit] != 0) 10097e911b15Skarels return(EBUSY); 10107e911b15Skarels else 10117e911b15Skarels one_only[unit] = 1; 10127e911b15Skarels 10137e911b15Skarels qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ 10147e911b15Skarels 10157e911b15Skarels /* enble kbd & mouse intrpts in DUART mask reg */ 10167e911b15Skarels 10177e911b15Skarels qdflags[unit].duart_imask |= 0x22; 10187e911b15Skarels duart->imask = qdflags[unit].duart_imask; 10197e911b15Skarels 1020*e977faadSmarc /*------------------------------------------------------------------ 1021*e977faadSmarc * if the open call is to the console or the alternate console... */ 1022*e977faadSmarc 1023*e977faadSmarc } else if ((minor_dev & 0x03) != 2) { 10247e911b15Skarels 10257e911b15Skarels qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ 10267e911b15Skarels dga->csr |= CURS_ENB; 10277e911b15Skarels 10287e911b15Skarels qdflags[unit].duart_imask |= 0x02; 10297e911b15Skarels duart->imask = qdflags[unit].duart_imask; 10307e911b15Skarels 10317e911b15Skarels /*------------------------------- 10327e911b15Skarels * some setup for tty handling */ 10337e911b15Skarels 10347e911b15Skarels tp = &qd_tty[minor_dev]; 10357e911b15Skarels 10367e911b15Skarels tp->t_addr = ui->ui_addr; 10377e911b15Skarels tp->t_oproc = qdstart; 1038*e977faadSmarc #ifdef notdef /* never */ 1039*e977faadSmarc /*--------------------------------------------------------------------- 1040*e977faadSmarc * Look at the compatibility mode to specify correct default parameters 1041*e977faadSmarc * and to insure only standard specified functionality. */ 1042*e977faadSmarc if ((u.u_procp->p_progenv == A_SYSV) || 1043*e977faadSmarc (u.u_procp->p_progenv == A_POSIX)) { 1044*e977faadSmarc flag |= O_TERMIO; 1045*e977faadSmarc tp->t_line = TERMIODISC; 1046*e977faadSmarc } 1047*e977faadSmarc #endif /*notdef*/ 10487e911b15Skarels 10497e911b15Skarels if ((tp->t_state & TS_ISOPEN) == 0) { 10507e911b15Skarels 10517e911b15Skarels ttychars(tp); 1052*e977faadSmarc tp->t_flags = IFLAGS; 10537e911b15Skarels tp->t_ispeed = B9600; 10547e911b15Skarels tp->t_ospeed = B9600; 1055*e977faadSmarc tp->t_state = TS_ISOPEN | TS_CARR_ON; 1056*e977faadSmarc 1057*e977faadSmarc #ifdef notdef /* never */ 1058*e977faadSmarc tp->t_cflag = tp->t_cflag_ext = B9600; 1059*e977faadSmarc tp->t_iflag_ext = 0; 1060*e977faadSmarc tp->t_oflag_ext = 0; 1061*e977faadSmarc tp->t_lflag_ext = 0; 10627e911b15Skarels 106324f67f6bSmarc if( (minor_dev & 0x03) == 0 ) { 1064*e977faadSmarc /*---------------------------------------------------- 1065*e977faadSmarc * Ultrix defaults to a "COOKED" mode on the first 1066*e977faadSmarc * open, while termio defaults to a "RAW" style. 1067*e977faadSmarc * Base this decision by a flag set in the termio 1068*e977faadSmarc * emulation routine for open, or set by an explicit 1069*e977faadSmarc * ioctl call. */ 1070*e977faadSmarc 1071*e977faadSmarc if ( flag & O_TERMIO ) { 1072*e977faadSmarc /*-------------------------------------- 1073*e977faadSmarc * Provide a termio style environment. 1074*e977faadSmarc * "RAW" style by default. */ 1075*e977faadSmarc 1076*e977faadSmarc tp->t_flags = RAW; 1077*e977faadSmarc tp->t_iflag = 0; 1078*e977faadSmarc tp->t_oflag = 0; 1079*e977faadSmarc tp->t_cflag |= CS8|CREAD|HUPCL; 1080*e977faadSmarc tp->t_lflag = 0; 1081*e977faadSmarc 1082*e977faadSmarc /*------------------------------------- 1083*e977faadSmarc * Change to System V line discipline.*/ 1084*e977faadSmarc 1085*e977faadSmarc tp->t_line = TERMIODISC; 1086*e977faadSmarc /*----------------------------------------- 1087*e977faadSmarc * The following three control chars have 1088*e977faadSmarc * different default values than ULTRIX. */ 1089*e977faadSmarc 1090*e977faadSmarc tp->t_cc[VERASE] = '#'; 1091*e977faadSmarc tp->t_cc[VKILL] = '@'; 1092*e977faadSmarc tp->t_cc[VINTR] = 0177; 1093*e977faadSmarc tp->t_cc[VMIN] = 6; 1094*e977faadSmarc tp->t_cc[VTIME] = 1; 1095*e977faadSmarc } else { 1096*e977faadSmarc /*-------------------------------------- 1097*e977faadSmarc * Provide a backward compatible ULTRIX 1098*e977faadSmarc * environment. "COOKED" style. */ 1099*e977faadSmarc 1100*e977faadSmarc tp->t_flags = IFLAGS; 1101*e977faadSmarc tp->t_iflag = IFLAG; 1102*e977faadSmarc tp->t_oflag = OFLAG; 1103*e977faadSmarc tp->t_lflag = LFLAG; 1104*e977faadSmarc tp->t_cflag |= CFLAG; 1105*e977faadSmarc } 110624f67f6bSmarc } 110724f67f6bSmarc else { 11087e911b15Skarels tp->t_flags = RAW; 1109*e977faadSmarc tp->t_iflag = 0; 1110*e977faadSmarc tp->t_oflag = 0; 1111*e977faadSmarc tp->t_cflag |= CS8|CREAD|HUPCL; 1112*e977faadSmarc tp->t_lflag = 0; 11137e911b15Skarels } 1114*e977faadSmarc if( (minor_dev & 0x03) == 1 ) 1115*e977faadSmarc tp->t_iflag |= IXOFF; /* flow control for qconsole */ 1116*e977faadSmarc #endif /*notdef*/ 111724f67f6bSmarc } 11187e911b15Skarels 11197e911b15Skarels /*---------------------------------------- 11207e911b15Skarels * enable intrpts, open line discipline */ 11217e911b15Skarels 11227e911b15Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 11237e911b15Skarels return ((*linesw[tp->t_line].l_open)(dev, tp)); 11247e911b15Skarels } 11257e911b15Skarels 11267e911b15Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 11277e911b15Skarels return(0); 11287e911b15Skarels 11297e911b15Skarels } /* qdopen */ 11307e911b15Skarels 11317e911b15Skarels /*************************************************************** 11327e911b15Skarels * 1133*e977faadSmarc * qdclose()... clean up on the way out 11347e911b15Skarels * 11357e911b15Skarels **************************************************************** 11367e911b15Skarels * 11377e911b15Skarels * calling convention: qdclose(); 11387e911b15Skarels * 11397e911b15Skarels * side effects: none 11407e911b15Skarels * 11417e911b15Skarels * return: none 11427e911b15Skarels * 11437e911b15Skarels *********************/ 11447e911b15Skarels 11457e911b15Skarels qdclose(dev, flag) 11467e911b15Skarels dev_t dev; 11477e911b15Skarels int flag; 11487e911b15Skarels { 11497e911b15Skarels register struct tty *tp; 11507e911b15Skarels register struct qdmap *qd; 11517e911b15Skarels register int *ptep; 11527e911b15Skarels int i; /* SIGNED index */ 11537e911b15Skarels 11547e911b15Skarels struct dga *dga; /* gate array register map pointer */ 11557e911b15Skarels struct duart *duart; 11567e911b15Skarels struct adder *adder; 11577e911b15Skarels 11587e911b15Skarels u_int unit; 11597e911b15Skarels u_int minor_dev; 11607e911b15Skarels u_int mapix; 11617e911b15Skarels 11627e911b15Skarels minor_dev = minor(dev); /* get minor device number */ 11637e911b15Skarels unit = minor_dev >> 2; /* get QDSS number */ 11647e911b15Skarels qd = &qdmap[unit]; 11657e911b15Skarels 1166*e977faadSmarc /*------------------------------------ 1167*e977faadSmarc * if this is the graphic device... */ 11687e911b15Skarels 11697e911b15Skarels if ((minor_dev & 0x03) == 2) { 1170*e977faadSmarc 1171*e977faadSmarc /*----------------- 1172*e977faadSmarc * unlock driver */ 1173*e977faadSmarc 1174*e977faadSmarc if (one_only[unit] != 1) 11757e911b15Skarels return(EBUSY); 11767e911b15Skarels else 11777e911b15Skarels one_only[unit] = 0; 11787e911b15Skarels 1179*e977faadSmarc /*---------------------------- 1180*e977faadSmarc * re-protect device memory */ 11817e911b15Skarels 11827e911b15Skarels if (qdflags[unit].mapped & MAPDEV) { 11837e911b15Skarels 1184*e977faadSmarc /*---------------- 1185*e977faadSmarc * TEMPLATE RAM */ 11867e911b15Skarels 118724f67f6bSmarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 118824f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 11897e911b15Skarels 11907e911b15Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 11917e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 11927e911b15Skarels 1193*e977faadSmarc /*--------- 1194*e977faadSmarc * ADDER */ 11957e911b15Skarels 119624f67f6bSmarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 119724f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 11987e911b15Skarels 11997e911b15Skarels for (i = VTOP(REGSIZE); i > 0; --i) 12007e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 12017e911b15Skarels 1202*e977faadSmarc /*-------------- 1203*e977faadSmarc * COLOR MAPS */ 12047e911b15Skarels 120524f67f6bSmarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 120624f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 12077e911b15Skarels 12087e911b15Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 12097e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 12107e911b15Skarels } 12117e911b15Skarels 1212*e977faadSmarc /*---------------------------------------------------- 1213*e977faadSmarc * re-protect DMA buffer and free the map registers */ 12147e911b15Skarels 12157e911b15Skarels if (qdflags[unit].mapped & MAPDMA) { 12167e911b15Skarels 12177e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 12187e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 12197e911b15Skarels 12207e911b15Skarels dga->csr &= ~DMA_IE; 12217e911b15Skarels dga->csr &= ~0x0600; /* kill DMA */ 12227e911b15Skarels adder->command = CANCEL; 12237e911b15Skarels 12247e911b15Skarels /* if DMA was running, flush spurious intrpt */ 12257e911b15Skarels 12267e911b15Skarels if (dga->bytcnt_lo != 0) { 12277e911b15Skarels dga->bytcnt_lo = 0; 12287e911b15Skarels dga->bytcnt_hi = 0; 12297e911b15Skarels DMA_SETIGNORE(DMAheader[unit]); 12307e911b15Skarels dga->csr |= DMA_IE; 12317e911b15Skarels dga->csr &= ~DMA_IE; 12327e911b15Skarels } 12337e911b15Skarels 12347e911b15Skarels ptep = (int *) 12357e911b15Skarels ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); 12367e911b15Skarels 12377e911b15Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 12387e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 12397e911b15Skarels 12407e911b15Skarels ubarelse(0, &Qbus_unmap[unit]); 12417e911b15Skarels } 12427e911b15Skarels 1243*e977faadSmarc /*--------------------------------------- 1244*e977faadSmarc * re-protect 1K (2 pages) event queue */ 12457e911b15Skarels 12467e911b15Skarels if (qdflags[unit].mapped & MAPEQ) { 12477e911b15Skarels 12487e911b15Skarels ptep = (int *) 12497e911b15Skarels ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); 12507e911b15Skarels 12517e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 12527e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 12537e911b15Skarels } 12547e911b15Skarels 1255*e977faadSmarc /*------------------------------------------------------------ 1256*e977faadSmarc * re-protect scroll param area and disable scroll intrpts */ 12577e911b15Skarels 12587e911b15Skarels if (qdflags[unit].mapped & MAPSCR) { 12597e911b15Skarels 12607e911b15Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 12617e911b15Skarels + (mfpr(SBR) | 0x80000000)); 12627e911b15Skarels 12637e911b15Skarels /* re-protect 512 scroll param area */ 12647e911b15Skarels 12657e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 12667e911b15Skarels 12677e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 12687e911b15Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 12697e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 12707e911b15Skarels } 12717e911b15Skarels 1272*e977faadSmarc /*----------------------------------------------------------- 1273*e977faadSmarc * re-protect color map write buffer area and kill intrpts */ 12747e911b15Skarels 12757e911b15Skarels if (qdflags[unit].mapped & MAPCOLOR) { 12767e911b15Skarels 12777e911b15Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 12787e911b15Skarels + (mfpr(SBR) | 0x80000000)); 12797e911b15Skarels 12807e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 12817e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 12827e911b15Skarels 12837e911b15Skarels color_buf[unit]->status = 0; 12847e911b15Skarels 12857e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 12867e911b15Skarels qdflags[unit].adder_ie &= ~VSYNC; 12877e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 12887e911b15Skarels } 12897e911b15Skarels 1290*e977faadSmarc /*----------------------------------- 1291*e977faadSmarc * flag that everthing is unmapped */ 12927e911b15Skarels 1293*e977faadSmarc mtpr(TBIA, 0); /* smash CPU's translation buf */ 1294*e977faadSmarc qdflags[unit].mapped = 0; /* flag everything now unmapped */ 12957e911b15Skarels qdflags[unit].inuse &= ~GRAPHIC_DEV; 12967e911b15Skarels qdflags[unit].curs_acc = ACC_OFF; 12977e911b15Skarels qdflags[unit].curs_thr = 128; 12987e911b15Skarels 1299*e977faadSmarc /*--------------------- 1300*e977faadSmarc * restore the console */ 13017e911b15Skarels 13027e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 13037e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 13047e911b15Skarels 13057e911b15Skarels dga->csr &= ~DMA_IE; 13067e911b15Skarels dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ 13077e911b15Skarels dga->csr |= DMA_ERR; /* clear error condition */ 13087e911b15Skarels adder->command = CANCEL; 13097e911b15Skarels 13107e911b15Skarels /* if DMA was running, flush spurious intrpt */ 13117e911b15Skarels 13127e911b15Skarels if (dga->bytcnt_lo != 0) { 13137e911b15Skarels dga->bytcnt_lo = 0; 13147e911b15Skarels dga->bytcnt_hi = 0; 13157e911b15Skarels DMA_SETIGNORE(DMAheader[unit]); 13167e911b15Skarels dga->csr |= DMA_IE; 13177e911b15Skarels dga->csr &= ~DMA_IE; 13187e911b15Skarels } 13197e911b15Skarels 13207e911b15Skarels init_shared(unit); /* init shared memory */ 13217e911b15Skarels setup_dragon(unit); /* init ADDER/VIPER */ 13227e911b15Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 13237e911b15Skarels setup_input(unit); /* init the DUART */ 13247e911b15Skarels ldfont(unit); 13257e911b15Skarels cursor[unit].x = 0; 13267e911b15Skarels cursor[unit].y = 0; 13277e911b15Skarels 1328*e977faadSmarc /* shut off the mouse rcv intrpt and turn on kbd intrpts */ 1329*e977faadSmarc 13307e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 13317e911b15Skarels qdflags[unit].duart_imask &= ~(0x20); 13327e911b15Skarels qdflags[unit].duart_imask |= 0x02; 13337e911b15Skarels duart->imask = qdflags[unit].duart_imask; 1334*e977faadSmarc 1335*e977faadSmarc /*----------------------------------------- 1336*e977faadSmarc * shut off interrupts if all is closed */ 1337*e977faadSmarc 13387e911b15Skarels if (!(qdflags[unit].inuse & (CONS_DEV | ALTCONS_DEV))) { 1339*e977faadSmarc 13407e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 13417e911b15Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 13427e911b15Skarels } 13437e911b15Skarels } 1344*e977faadSmarc 1345*e977faadSmarc /*---------------------------------------------------- 1346*e977faadSmarc * if this is the console or the alternate console */ 1347*e977faadSmarc 1348*e977faadSmarc else { 1349*e977faadSmarc 13507e911b15Skarels tp = &qd_tty[minor_dev]; 13517e911b15Skarels 13527e911b15Skarels (*linesw[tp->t_line].l_close)(tp); 13537e911b15Skarels ttyclose(tp); 1354*e977faadSmarc 13557e911b15Skarels tp->t_state = 0; 1356*e977faadSmarc /* Remove termio flags that do not map */ 1357*e977faadSmarc #ifdef notdef /* never */ 1358*e977faadSmarc tp->t_iflag &= ~TERMIO_ONLY_IFLAG; 1359*e977faadSmarc tp->t_oflag &= ~TERMIO_ONLY_OFLAG; 1360*e977faadSmarc tp->t_cflag &= ~TERMIO_ONLY_CFLAG; 1361*e977faadSmarc tp->t_lflag &= ~TERMIO_ONLY_LFLAG; 1362*e977faadSmarc #endif /*notdef*/ 1363*e977faadSmarc 13647e911b15Skarels qdflags[unit].inuse &= ~CONS_DEV; 1365*e977faadSmarc 1366*e977faadSmarc /*------------------------------------------------- 1367*e977faadSmarc * if graphics device is closed, kill interrupts */ 1368*e977faadSmarc 13697e911b15Skarels if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { 13707e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 13717e911b15Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 13727e911b15Skarels } 13737e911b15Skarels } 13747e911b15Skarels 1375*e977faadSmarc /*-------- 1376*e977faadSmarc * exit */ 1377*e977faadSmarc 13787e911b15Skarels return(0); 13797e911b15Skarels 13807e911b15Skarels } /* qdclose */ 13817e911b15Skarels 13827e911b15Skarels /*************************************************************** 13837e911b15Skarels * 1384*e977faadSmarc * qdioctl()... provide QDSS control services 13857e911b15Skarels * 13867e911b15Skarels **************************************************************** 13877e911b15Skarels * 13887e911b15Skarels * calling convention: qdioctl(dev, cmd, datap, flags); 13897e911b15Skarels * 13907e911b15Skarels * where: dev - the major/minor device number 13917e911b15Skarels * cmd - the user-passed command argument 13927e911b15Skarels * datap - ptr to user input buff (128 bytes max) 13937e911b15Skarels * flags - "f_flags" from "struct file" in file.h 13947e911b15Skarels * 13957e911b15Skarels * 13967e911b15Skarels * - here is the format for the input "cmd" argument 13977e911b15Skarels * 13987e911b15Skarels * 31 29 28 23 22 16 15 8 7 0 13997e911b15Skarels * +----------------------------------------------------------------+ 14007e911b15Skarels * |I/O type| | buff length | device ID char | user command | 14017e911b15Skarels * +----------------------------------------------------------------+ 14027e911b15Skarels * 14037e911b15Skarels * Return data is in the data buffer pointed to by "datap" input spec 14047e911b15Skarels * 14057e911b15Skarels *********************/ 14067e911b15Skarels 14077e911b15Skarels qdioctl(dev, cmd, datap, flags) 14087e911b15Skarels dev_t dev; 14097e911b15Skarels int cmd; 14107e911b15Skarels caddr_t datap; 14117e911b15Skarels int flags; 14127e911b15Skarels { 14137e911b15Skarels register int *ptep; /* page table entry pointer */ 141424f67f6bSmarc register int mapix; /* QVmap[] page table index */ 14157e911b15Skarels register struct _vs_event *event; 14167e911b15Skarels register struct tty *tp; 1417*e977faadSmarc 14187e911b15Skarels struct qdmap *qd; /* pointer to device map struct */ 14197e911b15Skarels struct dga *dga; /* Gate Array reg structure pntr */ 14207e911b15Skarels struct duart *duart; /* DUART reg structure pointer */ 14217e911b15Skarels struct adder *adder; /* ADDER reg structure pointer */ 1422*e977faadSmarc 14237e911b15Skarels struct prgkbd *cmdbuf; 14247e911b15Skarels struct prg_cursor *curs; 14257e911b15Skarels struct _vs_cursor *pos; 1426*e977faadSmarc 14277e911b15Skarels u_int unit = minor(dev) >> 2; /* number of caller's QDSS */ 14287e911b15Skarels u_int minor_dev = minor(dev); 14297e911b15Skarels struct uba_device *ui = qdinfo[unit]; 14307e911b15Skarels struct qd_softc *sc = &qd_softc[ui->ui_unit]; 1431*e977faadSmarc #ifdef notdef 1432*e977faadSmarc struct devget *devget; 1433*e977faadSmarc #endif 1434*e977faadSmarc 14357e911b15Skarels int error; 14367e911b15Skarels int s; 1437*e977faadSmarc 14387e911b15Skarels int i; /* SIGNED index */ 14397e911b15Skarels int sbr; /* SBR variable (you silly boy) */ 14407e911b15Skarels u_int ix; 1441*e977faadSmarc 14427e911b15Skarels short status; 14437e911b15Skarels short *shortp; /* generic pointer to a short */ 14447e911b15Skarels char *chrp; /* generic character pointer */ 1445*e977faadSmarc 14467e911b15Skarels short *temp; /* a pointer to template RAM */ 14477e911b15Skarels 1448*e977faadSmarc /*----------------------------------------- 1449*e977faadSmarc * service graphic device ioctl commands */ 1450*e977faadSmarc 14517e911b15Skarels switch (cmd) { 1452*e977faadSmarc 1453*e977faadSmarc /*------------------------------------------------- 1454*e977faadSmarc * extract the oldest event from the event queue */ 1455*e977faadSmarc 14567e911b15Skarels case QD_GETEVENT: 1457*e977faadSmarc 14587e911b15Skarels if (ISEMPTY(eq_header[unit])) { 14597e911b15Skarels event = (struct _vs_event *) datap; 14607e911b15Skarels event->vse_device = VSE_NULL; 14617e911b15Skarels break; 14627e911b15Skarels } 1463*e977faadSmarc 14647e911b15Skarels event = (struct _vs_event *) GETBEGIN(eq_header[unit]); 1465*e977faadSmarc s = spl5(); 14667e911b15Skarels GETEND(eq_header[unit]); 14677e911b15Skarels splx(s); 14687e911b15Skarels bcopy(event, datap, sizeof(struct _vs_event)); 14697e911b15Skarels break; 14707e911b15Skarels 14717e911b15Skarels /*------------------------------------------------------- 14727e911b15Skarels * init the dragon stuff, DUART, and driver variables */ 14737e911b15Skarels 14747e911b15Skarels case QD_RESET: 14757e911b15Skarels 14767e911b15Skarels init_shared(unit); /* init shared memory */ 14777e911b15Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 14787e911b15Skarels clear_qd_screen(unit); 14797e911b15Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 14807e911b15Skarels ldfont(unit); /* load the console font */ 14817e911b15Skarels setup_input(unit); /* init the DUART */ 14827e911b15Skarels break; 14837e911b15Skarels 14847e911b15Skarels /*---------------------------------------- 14857e911b15Skarels * init the DUART and driver variables */ 14867e911b15Skarels 14877e911b15Skarels case QD_SET: 14887e911b15Skarels 14897e911b15Skarels init_shared(unit); 14907e911b15Skarels setup_input(unit); 14917e911b15Skarels break; 14927e911b15Skarels 14937e911b15Skarels /*--------------------------------------------------------------- 14947e911b15Skarels * clear the QDSS screen. (NOTE that this reinits the dragon) */ 14957e911b15Skarels 14967e911b15Skarels case QD_CLRSCRN: 14977e911b15Skarels 1498*e977faadSmarc #ifdef notdef /* has caused problems and is not necessary */ 14997e911b15Skarels setup_dragon(unit); 15007e911b15Skarels clear_qd_screen(unit); 1501*e977faadSmarc #endif 15027e911b15Skarels break; 15037e911b15Skarels 15047e911b15Skarels /*------------------------------------ 15057e911b15Skarels * load a cursor into template RAM */ 15067e911b15Skarels 15077e911b15Skarels case QD_WTCURSOR: 15087e911b15Skarels 15097e911b15Skarels ldcursor(unit, datap); 15107e911b15Skarels break; 15117e911b15Skarels 15127e911b15Skarels case QD_RDCURSOR: 15137e911b15Skarels 15147e911b15Skarels temp = (short *) qdmap[unit].template; 15157e911b15Skarels 15167e911b15Skarels /* cursor is 32 WORDS from the end of the 8k WORD... 15177e911b15Skarels * ...template space */ 15187e911b15Skarels 15197e911b15Skarels temp += (8 * 1024) - 32; 15207e911b15Skarels 15217e911b15Skarels for (i = 0; i < 32; ++i, datap += sizeof(short)) 15227e911b15Skarels *(short *)datap = *temp++; 15237e911b15Skarels break; 15247e911b15Skarels 15257e911b15Skarels /*------------------------------ 15267e911b15Skarels * position the mouse cursor */ 15277e911b15Skarels 15287e911b15Skarels case QD_POSCURSOR: 15297e911b15Skarels 15307e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 15317e911b15Skarels pos = (struct _vs_cursor *) datap; 1532*e977faadSmarc s = spl5(); 15337e911b15Skarels dga->x_cursor = TRANX(pos->x); 15347e911b15Skarels dga->y_cursor = TRANY(pos->y); 15357e911b15Skarels eq_header[unit]->curs_pos.x = pos->x; 15367e911b15Skarels eq_header[unit]->curs_pos.y = pos->y; 15377e911b15Skarels splx(s); 15387e911b15Skarels break; 15397e911b15Skarels 15407e911b15Skarels /*-------------------------------------- 15417e911b15Skarels * set the cursor acceleration factor */ 15427e911b15Skarels 15437e911b15Skarels case QD_PRGCURSOR: 15447e911b15Skarels 15457e911b15Skarels curs = (struct prg_cursor *) datap; 1546*e977faadSmarc s = spl5(); 15477e911b15Skarels qdflags[unit].curs_acc = curs->acc_factor; 15487e911b15Skarels qdflags[unit].curs_thr = curs->threshold; 15497e911b15Skarels splx(s); 15507e911b15Skarels break; 15517e911b15Skarels 15527e911b15Skarels /*--------------------------------------- 15537e911b15Skarels * enable 'user write' to device pages */ 15547e911b15Skarels 15557e911b15Skarels case QD_MAPDEVICE: 15567e911b15Skarels 15577e911b15Skarels /*-------------- 15587e911b15Skarels * init stuff */ 15597e911b15Skarels 15607e911b15Skarels qdflags[unit].mapped |= MAPDEV; 15617e911b15Skarels qd = (struct qdmap *) &qdmap[unit]; 15627e911b15Skarels 15637e911b15Skarels /*------------------------------------- 15647e911b15Skarels * enable user write to template RAM */ 15657e911b15Skarels 156624f67f6bSmarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 156724f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 15687e911b15Skarels 15697e911b15Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 15707e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 15717e911b15Skarels 15727e911b15Skarels /*---------------------------------- 15737e911b15Skarels * enable user write to registers */ 15747e911b15Skarels 157524f67f6bSmarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 157624f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 15777e911b15Skarels 15787e911b15Skarels for (i = VTOP(REGSIZE); i > 0; --i) 15797e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 15807e911b15Skarels 15817e911b15Skarels /*----------------------------------- 15827e911b15Skarels * enable user write to color maps */ 15837e911b15Skarels 158424f67f6bSmarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 158524f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 15867e911b15Skarels 15877e911b15Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 15887e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 15897e911b15Skarels 15907e911b15Skarels /*------------------------------ 15917e911b15Skarels * enable user write to DUART */ 15927e911b15Skarels 159324f67f6bSmarc mapix = VTOP((int)qd->duart) - VTOP(qvmem[0]); 159424f67f6bSmarc ptep = (int *)(QVmap[0] + mapix); 15957e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ 15967e911b15Skarels 15977e911b15Skarels mtpr(TBIA, 0); /* smash CPU's translation buffer */ 15987e911b15Skarels 15997e911b15Skarels /*------------------------------------------ 16007e911b15Skarels * stuff qdmap structure in return buffer */ 16017e911b15Skarels 16027e911b15Skarels bcopy(qd, datap, sizeof(struct qdmap)); 16037e911b15Skarels break; 16047e911b15Skarels 16057e911b15Skarels /*------------------------------------- 16067e911b15Skarels * do setup for DMA by user process */ 16077e911b15Skarels 16087e911b15Skarels case QD_MAPIOBUF: 16097e911b15Skarels 16107e911b15Skarels /*------------------------------------------------ 16117e911b15Skarels * set 'user write enable' bits for DMA buffer */ 16127e911b15Skarels 16137e911b15Skarels qdflags[unit].mapped |= MAPDMA; 16147e911b15Skarels 16157e911b15Skarels ptep = (int *) ((VTOP(DMAheader[unit]) * 4) 16167e911b15Skarels + (mfpr(SBR) | 0x80000000)); 16177e911b15Skarels 16187e911b15Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 16197e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 16207e911b15Skarels 16217e911b15Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 16227e911b15Skarels 16237e911b15Skarels /*------------------------------------- 16247e911b15Skarels * set up QBUS map registers for DMA */ 16257e911b15Skarels 16267e911b15Skarels DMAheader[unit]->QBAreg = 16277e911b15Skarels uballoc(0, DMAheader[unit], DMAbuf_size, 0); 16287e911b15Skarels 16297e911b15Skarels if (DMAheader[unit]->QBAreg == 0) 1630*e977faadSmarc printf("\nqd%d: qdioctl: QBA setup error", unit); 16317e911b15Skarels 16327e911b15Skarels Qbus_unmap[unit] = DMAheader[unit]->QBAreg; 16337e911b15Skarels DMAheader[unit]->QBAreg &= 0x3FFFF; 16347e911b15Skarels 16357e911b15Skarels /*---------------------- 16367e911b15Skarels * return I/O buf adr */ 16377e911b15Skarels 16387e911b15Skarels *(int *)datap = (int) DMAheader[unit]; 16397e911b15Skarels break; 16407e911b15Skarels 16417e911b15Skarels /*---------------------------------------------------------------- 16427e911b15Skarels * map the shared scroll param area and enable scroll interpts */ 16437e911b15Skarels 16447e911b15Skarels case QD_MAPSCROLL: 16457e911b15Skarels 16467e911b15Skarels qdflags[unit].mapped |= MAPSCR; 16477e911b15Skarels 16487e911b15Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 16497e911b15Skarels + (mfpr(SBR) | 0x80000000)); 16507e911b15Skarels 16517e911b15Skarels /* allow user write to scroll area */ 16527e911b15Skarels 16537e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 16547e911b15Skarels 16557e911b15Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 16567e911b15Skarels 16577e911b15Skarels scroll[unit]->status = 0; 16587e911b15Skarels 16597e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 16607e911b15Skarels 16617e911b15Skarels qdflags[unit].adder_ie |= FRAME_SYNC; 16627e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 16637e911b15Skarels 1664*e977faadSmarc 16657e911b15Skarels /* return scroll area address */ 16667e911b15Skarels 16677e911b15Skarels *(int *)datap = (int) scroll[unit]; 16687e911b15Skarels break; 16697e911b15Skarels 16707e911b15Skarels /*------------------------------------------------------------- 16717e911b15Skarels * unmap shared scroll param area and disable scroll intrpts */ 16727e911b15Skarels 16737e911b15Skarels case QD_UNMAPSCROLL: 16747e911b15Skarels 16757e911b15Skarels if (qdflags[unit].mapped & MAPSCR) { 16767e911b15Skarels 16777e911b15Skarels qdflags[unit].mapped &= ~MAPSCR; 16787e911b15Skarels 16797e911b15Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 16807e911b15Skarels + (mfpr(SBR) | 0x80000000)); 16817e911b15Skarels 16827e911b15Skarels /* re-protect 512 scroll param area */ 16837e911b15Skarels 16847e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 16857e911b15Skarels 16867e911b15Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 16877e911b15Skarels 16887e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 16897e911b15Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 16907e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 16917e911b15Skarels } 16927e911b15Skarels break; 16937e911b15Skarels 16947e911b15Skarels /*----------------------------------------------------------- 16957e911b15Skarels * map shared color map write buf and turn on vsync intrpt */ 16967e911b15Skarels 16977e911b15Skarels case QD_MAPCOLOR: 16987e911b15Skarels 16997e911b15Skarels qdflags[unit].mapped |= MAPCOLOR; 17007e911b15Skarels 17017e911b15Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 17027e911b15Skarels + (mfpr(SBR) | 0x80000000)); 17037e911b15Skarels 17047e911b15Skarels /* allow user write to color map write buffer */ 17057e911b15Skarels 17067e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 17077e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 17087e911b15Skarels 17097e911b15Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 17107e911b15Skarels 1711*e977faadSmarc adder = (struct adder *) qdmap[unit].adder. 17127e911b15Skarels qdflags[unit].adder_ie |= VSYNC; 17137e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 17147e911b15Skarels 1715*e977faadSmarc /* return color area address */ 17167e911b15Skarels 17177e911b15Skarels *(int *)datap = (int) color_buf[unit]; 17187e911b15Skarels break; 17197e911b15Skarels 17207e911b15Skarels /*-------------------------------------------------------------- 17217e911b15Skarels * unmap shared color map write buffer and kill VSYNC intrpts */ 17227e911b15Skarels 17237e911b15Skarels case QD_UNMAPCOLOR: 17247e911b15Skarels 17257e911b15Skarels if (qdflags[unit].mapped & MAPCOLOR) { 17267e911b15Skarels 17277e911b15Skarels qdflags[unit].mapped &= ~MAPCOLOR; 17287e911b15Skarels 17297e911b15Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 17307e911b15Skarels + (mfpr(SBR) | 0x80000000)); 17317e911b15Skarels 17327e911b15Skarels /* re-protect color map write buffer */ 17337e911b15Skarels 17347e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 17357e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 17367e911b15Skarels 17377e911b15Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 17387e911b15Skarels 17397e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 17407e911b15Skarels 17417e911b15Skarels qdflags[unit].adder_ie &= ~VSYNC; 17427e911b15Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 17437e911b15Skarels } 17447e911b15Skarels break; 17457e911b15Skarels 17467e911b15Skarels /*--------------------------------------------- 17477e911b15Skarels * give user write access to the event queue */ 17487e911b15Skarels 17497e911b15Skarels case QD_MAPEVENT: 17507e911b15Skarels 17517e911b15Skarels qdflags[unit].mapped |= MAPEQ; 17527e911b15Skarels 17537e911b15Skarels ptep = (int *) ((VTOP(eq_header[unit]) * 4) 17547e911b15Skarels + (mfpr(SBR) | 0x80000000)); 17557e911b15Skarels 17567e911b15Skarels /* allow user write to 1K event queue */ 17577e911b15Skarels 17587e911b15Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 17597e911b15Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 17607e911b15Skarels 17617e911b15Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 17627e911b15Skarels 17637e911b15Skarels /* return event queue address */ 17647e911b15Skarels 17657e911b15Skarels *(int *)datap = (int) eq_header[unit]; 17667e911b15Skarels break; 17677e911b15Skarels 17687e911b15Skarels /*----------------------------------------------- 17697e911b15Skarels * pass caller's programming commands to LK201 */ 17707e911b15Skarels 17717e911b15Skarels case QD_PRGKBD: 17727e911b15Skarels 17737e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 17747e911b15Skarels cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ 17757e911b15Skarels 17767e911b15Skarels /*---------------- 17777e911b15Skarels * send command */ 17787e911b15Skarels 17797e911b15Skarels for (i = 1000; i > 0; --i) { 17807e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 17817e911b15Skarels duart->dataA = cmdbuf->cmd; 17827e911b15Skarels break; 17837e911b15Skarels } 17847e911b15Skarels } 17857e911b15Skarels 17867e911b15Skarels if (i == 0) { 1787*e977faadSmarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [1]", unit); 17887e911b15Skarels break; 17897e911b15Skarels } 17907e911b15Skarels 17917e911b15Skarels /*---------------- 17927e911b15Skarels * send param1? */ 17937e911b15Skarels 17947e911b15Skarels if (cmdbuf->cmd & LAST_PARAM) 17957e911b15Skarels break; 17967e911b15Skarels 17977e911b15Skarels for (i = 1000; i > 0; --i) { 17987e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 17997e911b15Skarels duart->dataA = cmdbuf->param1; 18007e911b15Skarels break; 18017e911b15Skarels } 18027e911b15Skarels } 18037e911b15Skarels 18047e911b15Skarels if (i == 0) { 1805*e977faadSmarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [2]", unit); 18067e911b15Skarels break; 18077e911b15Skarels } 18087e911b15Skarels 18097e911b15Skarels /*---------------- 18107e911b15Skarels * send param2? */ 18117e911b15Skarels 18127e911b15Skarels if (cmdbuf->param1 & LAST_PARAM) 18137e911b15Skarels break; 18147e911b15Skarels 18157e911b15Skarels for (i = 1000; i > 0; --i) { 18167e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 18177e911b15Skarels duart->dataA = cmdbuf->param2; 18187e911b15Skarels break; 18197e911b15Skarels } 18207e911b15Skarels } 18217e911b15Skarels 18227e911b15Skarels if (i == 0) { 1823*e977faadSmarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [3]", unit); 18247e911b15Skarels break; 18257e911b15Skarels } 18267e911b15Skarels 18277e911b15Skarels break; 18287e911b15Skarels 18297e911b15Skarels /*---------------------------------------------------- 18307e911b15Skarels * pass caller's programming commands to the mouse */ 18317e911b15Skarels 18327e911b15Skarels case QD_PRGMOUSE: 18337e911b15Skarels 18347e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 18357e911b15Skarels 18367e911b15Skarels for (i = 1000; i > 0; --i) { 18377e911b15Skarels if ((status = duart->statusB) & XMT_RDY) { 18387e911b15Skarels duart->dataB = *datap; 18397e911b15Skarels break; 18407e911b15Skarels } 18417e911b15Skarels } 18427e911b15Skarels 18437e911b15Skarels if (i == 0) { 1844*e977faadSmarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [4]", unit); 18457e911b15Skarels } 18467e911b15Skarels 18477e911b15Skarels break; 18487e911b15Skarels 18497e911b15Skarels /*---------------------------------------------- 18507e911b15Skarels * get QDSS configuration word and return it */ 18517e911b15Skarels 18527e911b15Skarels case QD_RDCONFIG: 18537e911b15Skarels 18547e911b15Skarels *(short *)datap = qdflags[unit].config; 18557e911b15Skarels break; 18567e911b15Skarels 1857*e977faadSmarc /*-------------------------------------------------------------- 1858*e977faadSmarc * re-route kernel console messages to the alternate console */ 1859*e977faadSmarc 1860*e977faadSmarc case QD_KERN_LOOP: 1861*e977faadSmarc 1862*e977faadSmarc qdflags[unit].kernel_loop = -1; 1863*e977faadSmarc break; 1864*e977faadSmarc 1865*e977faadSmarc case QD_KERN_UNLOOP: 1866*e977faadSmarc 1867*e977faadSmarc qdflags[unit].kernel_loop = 0; 1868*e977faadSmarc break; 1869*e977faadSmarc 18707e911b15Skarels /*---------------------- 18717e911b15Skarels * program the tablet */ 18727e911b15Skarels 18737e911b15Skarels case QD_PRGTABLET: 18747e911b15Skarels 18757e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 18767e911b15Skarels 18777e911b15Skarels for (i = 1000; i > 0; --i) { 18787e911b15Skarels if ((status = duart->statusB) & XMT_RDY) { 18797e911b15Skarels duart->dataB = *datap; 18807e911b15Skarels break; 18817e911b15Skarels } 18827e911b15Skarels } 18837e911b15Skarels 18847e911b15Skarels if (i == 0) { 1885*e977faadSmarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [5]", unit); 18867e911b15Skarels } 18877e911b15Skarels 18887e911b15Skarels break; 18897e911b15Skarels 18907e911b15Skarels /*----------------------------------------------- 18917e911b15Skarels * program the tablet report resolution factor */ 18927e911b15Skarels 18937e911b15Skarels case QD_PRGTABRES: 18947e911b15Skarels 18957e911b15Skarels qdflags[unit].tab_res = *(short *)datap; 18967e911b15Skarels break; 1897*e977faadSmarc #ifdef notdef /* never */ 1898*e977faadSmarc case DEVIOCGET: /* device status */ 1899*e977faadSmarc devget = (struct devget *)datap; 1900*e977faadSmarc bzero(devget,sizeof(struct devget)); 1901*e977faadSmarc devget->category = DEV_TERMINAL; 1902*e977faadSmarc devget->bus = DEV_QB; 1903*e977faadSmarc bcopy(DEV_VCB02,devget->interface, 1904*e977faadSmarc strlen(DEV_VCB02)); 1905*e977faadSmarc bcopy(DEV_VR290,devget->device, 1906*e977faadSmarc strlen(DEV_VR290)); /* terminal */ 1907*e977faadSmarc devget->adpt_num = ui->ui_adpt; /* which adapter*/ 1908*e977faadSmarc devget->nexus_num = ui->ui_nexus; /* which nexus */ 1909*e977faadSmarc devget->bus_num = ui->ui_ubanum; /* which QB */ 1910*e977faadSmarc devget->ctlr_num = unit; /* which interf.*/ 1911*e977faadSmarc devget->slave_num = unit; /* which line */ 1912*e977faadSmarc bcopy(ui->ui_driver->ud_dname, 1913*e977faadSmarc devget->dev_name, 1914*e977faadSmarc strlen(ui->ui_driver->ud_dname)); /* Ultrix "qd" */ 1915*e977faadSmarc devget->unit_num = unit; /* qd line? */ 1916*e977faadSmarc devget->soft_count = 1917*e977faadSmarc sc->sc_softcnt; /* soft er. cnt.*/ 1918*e977faadSmarc devget->hard_count = 1919*e977faadSmarc sc->sc_hardcnt; /* hard er cnt. */ 1920*e977faadSmarc devget->stat = sc->sc_flags; /* status */ 1921*e977faadSmarc devget->category_stat = 1922*e977faadSmarc sc->sc_category_flags; /* cat. stat. */ 19238a2bf9b0Smarc break; 1924*e977faadSmarc #endif /*notdef*/ 19258a2bf9b0Smarc 19267e911b15Skarels default: 19277e911b15Skarels /*----------------------------- 19287e911b15Skarels * service tty type ioctl's */ 19297e911b15Skarels 19307e911b15Skarels if (!(minor_dev & 0x02)) { 19317e911b15Skarels 19327e911b15Skarels tp = &qd_tty[minor_dev]; 19337e911b15Skarels 19347e911b15Skarels error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); 19357e911b15Skarels if (error >= 0) { 19367e911b15Skarels return(error); 19377e911b15Skarels } 19387e911b15Skarels 19397e911b15Skarels error = ttioctl(tp, cmd, datap, flags); 19407e911b15Skarels if (error >= 0) { 19417e911b15Skarels return(error); 19427e911b15Skarels } 19437e911b15Skarels } 19447e911b15Skarels break; 19457e911b15Skarels } 19467e911b15Skarels 19477e911b15Skarels /*-------------------------------- 19487e911b15Skarels * clean up and get outta here */ 19497e911b15Skarels 19507e911b15Skarels return(0); 19517e911b15Skarels 19527e911b15Skarels } /* qdioctl */ 19537e911b15Skarels 19547e911b15Skarels /********************************************************************** 19557e911b15Skarels * 19567e911b15Skarels * qdselect()... service select call for event queue input 19577e911b15Skarels * 19587e911b15Skarels **********************************************************************/ 19597e911b15Skarels 19607e911b15Skarels qdselect(dev, rw) 19617e911b15Skarels dev_t dev; 19627e911b15Skarels int rw; 19637e911b15Skarels { 19647e911b15Skarels register int s; 19657e911b15Skarels register int unit; 1966*e977faadSmarc register struct tty *tp; 1967*e977faadSmarc u_int minor_dev = minor(dev); 19687e911b15Skarels 1969*e977faadSmarc s = spl5(); 1970*e977faadSmarc unit = minor_dev >> 2; 19717e911b15Skarels 19727e911b15Skarels switch (rw) { 19737e911b15Skarels 1974*e977faadSmarc case FREAD: 19757e911b15Skarels 1976*e977faadSmarc if ((minor_dev & 0x03) == 2) 1977*e977faadSmarc { 1978*e977faadSmarc /* 1979*e977faadSmarc * this is a graphics device, so check for events 1980*e977faadSmarc */ 1981*e977faadSmarc if(!(ISEMPTY(eq_header[unit]))) 1982*e977faadSmarc { 19837e911b15Skarels splx(s); 1984*e977faadSmarc return(1); 19857e911b15Skarels } 19867e911b15Skarels rsel[unit] = u.u_procp; 19877e911b15Skarels qdflags[unit].selmask |= SEL_READ; 19887e911b15Skarels splx(s); 19897e911b15Skarels return(0); 1990*e977faadSmarc } 1991*e977faadSmarc else 1992*e977faadSmarc { 1993*e977faadSmarc /* 1994*e977faadSmarc * this is a tty device 1995*e977faadSmarc */ 1996*e977faadSmarc tp = &qd_tty[minor_dev]; 1997*e977faadSmarc if (ttnread(tp)) 1998*e977faadSmarc return(1); 1999*e977faadSmarc tp->t_rsel = u.u_procp; 20007e911b15Skarels splx(s); 2001*e977faadSmarc return(0); 2002*e977faadSmarc } 2003*e977faadSmarc 2004*e977faadSmarc case FWRITE: 2005*e977faadSmarc 2006*e977faadSmarc if ((minor(dev) & 0x03) == 2) 2007*e977faadSmarc { 2008*e977faadSmarc /* 2009*e977faadSmarc * this is a graphics device, so check for dma buffers 2010*e977faadSmarc */ 2011*e977faadSmarc if (DMA_ISEMPTY(DMAheader[unit])) 2012*e977faadSmarc { 2013*e977faadSmarc splx(s); 2014*e977faadSmarc return(1); 20157e911b15Skarels } 20167e911b15Skarels rsel[unit] = u.u_procp; 20177e911b15Skarels qdflags[unit].selmask |= SEL_WRITE; 20187e911b15Skarels splx(s); 20197e911b15Skarels return(0); 20207e911b15Skarels } 2021*e977faadSmarc else 2022*e977faadSmarc { 2023*e977faadSmarc /* 2024*e977faadSmarc * this is a tty device 2025*e977faadSmarc */ 2026*e977faadSmarc tp = &qd_tty[minor_dev]; 2027*e977faadSmarc if (tp->t_outq.c_cc <= TTLOWAT(tp)) 2028*e977faadSmarc return(1); 2029*e977faadSmarc tp->t_wsel = u.u_procp; 2030*e977faadSmarc splx(s); 2031*e977faadSmarc return(0); 2032*e977faadSmarc } 2033*e977faadSmarc } 20347e911b15Skarels 20357e911b15Skarels } /* qdselect() */ 20367e911b15Skarels 20377e911b15Skarels /*************************************************************** 20387e911b15Skarels * 20397e911b15Skarels * qdwrite()... output to the QDSS screen as a TTY 20407e911b15Skarels * 20417e911b15Skarels ***************************************************************/ 20427e911b15Skarels 20437e911b15Skarels extern qd_strategy(); 20447e911b15Skarels 20457e911b15Skarels qdwrite(dev, uio) 20467e911b15Skarels dev_t dev; 20477e911b15Skarels struct uio *uio; 20487e911b15Skarels { 20497e911b15Skarels register struct tty *tp; 20507e911b15Skarels register int minor_dev; 20517e911b15Skarels register int unit; 20527e911b15Skarels 20537e911b15Skarels minor_dev = minor(dev); 20547e911b15Skarels unit = (minor_dev >> 2) & 0x07; 20557e911b15Skarels 20567e911b15Skarels /*------------------------------ 20577e911b15Skarels * if this is the console... */ 20587e911b15Skarels 20597e911b15Skarels if ((minor_dev & 0x03) != 0x02 && 20607e911b15Skarels qdflags[unit].inuse & CONS_DEV) { 20617e911b15Skarels tp = &qd_tty[minor_dev]; 20627e911b15Skarels return ((*linesw[tp->t_line].l_write)(tp, uio)); 20637e911b15Skarels } 20647e911b15Skarels 20657e911b15Skarels /*------------------------------------------------ 20667e911b15Skarels * else this must be a DMA xfer from user space */ 20677e911b15Skarels 20687e911b15Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 20697e911b15Skarels return (physio(qd_strategy, &qdbuf[unit], 20707e911b15Skarels dev, B_WRITE, minphys, uio)); 20717e911b15Skarels } 20727e911b15Skarels } 20737e911b15Skarels 20747e911b15Skarels /*************************************************************** 20757e911b15Skarels * 20767e911b15Skarels * qdread()... read from QDSS keyboard as a TTY 20777e911b15Skarels * 20787e911b15Skarels ***************************************************************/ 20797e911b15Skarels 20807e911b15Skarels qdread(dev, uio) 20817e911b15Skarels dev_t dev; 20827e911b15Skarels struct uio *uio; 20837e911b15Skarels { 20847e911b15Skarels register struct tty *tp; 20857e911b15Skarels register int minor_dev; 20867e911b15Skarels register int unit; 20877e911b15Skarels 20887e911b15Skarels minor_dev = minor(dev); 20897e911b15Skarels unit = (minor_dev >> 2) & 0x07; 20907e911b15Skarels 20917e911b15Skarels /*------------------------------ 20927e911b15Skarels * if this is the console... */ 20937e911b15Skarels 20947e911b15Skarels if ((minor_dev & 0x03) != 0x02 && 20957e911b15Skarels qdflags[unit].inuse & CONS_DEV) { 20967e911b15Skarels tp = &qd_tty[minor_dev]; 20977e911b15Skarels return ((*linesw[tp->t_line].l_read)(tp, uio)); 20987e911b15Skarels } 20997e911b15Skarels 21007e911b15Skarels /*------------------------------------------------ 21017e911b15Skarels * else this must be a bitmap-to-processor xfer */ 21027e911b15Skarels 21037e911b15Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 21047e911b15Skarels return (physio(qd_strategy, &qdbuf[unit], 21057e911b15Skarels dev, B_READ, minphys, uio)); 21067e911b15Skarels } 21077e911b15Skarels } 21087e911b15Skarels 21097e911b15Skarels /*************************************************************** 21107e911b15Skarels * 21117e911b15Skarels * qd_strategy()... strategy routine to do DMA 21127e911b15Skarels * 21137e911b15Skarels ***************************************************************/ 21147e911b15Skarels 21157e911b15Skarels qd_strategy(bp) 21167e911b15Skarels register struct buf *bp; 21177e911b15Skarels { 21187e911b15Skarels register struct dga *dga; 21197e911b15Skarels register struct adder *adder; 21207e911b15Skarels 21217e911b15Skarels char *DMAbufp; 21227e911b15Skarels 21237e911b15Skarels int QBAreg; 21247e911b15Skarels int bytcnt; 21257e911b15Skarels int s; 21267e911b15Skarels int unit; 21277e911b15Skarels int cookie; 21287e911b15Skarels 21297e911b15Skarels int i,j,k; 21307e911b15Skarels 21317e911b15Skarels unit = (minor(bp->b_dev) >> 2) & 0x07; 21327e911b15Skarels 2133*e977faadSmarc /*----------------- 2134*e977faadSmarc * init pointers */ 21357e911b15Skarels 21367e911b15Skarels if ((QBAreg = ubasetup(0, bp, 0)) == 0) { 2137*e977faadSmarc printf("\nqd%d: qd_strategy: QBA setup error", unit); 21387e911b15Skarels goto STRAT_ERR; 21397e911b15Skarels } 21407e911b15Skarels 21417e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 21427e911b15Skarels 2143*e977faadSmarc s = spl5(); 21447e911b15Skarels 21457e911b15Skarels qdflags[unit].user_dma = -1; 21467e911b15Skarels 21477e911b15Skarels dga->csr |= DMA_IE; 21487e911b15Skarels 21497e911b15Skarels cookie = QBAreg & 0x3FFFF; 21507e911b15Skarels dga->adrs_lo = (short) cookie; 21517e911b15Skarels dga->adrs_hi = (short) (cookie >> 16); 21527e911b15Skarels 21537e911b15Skarels dga->bytcnt_lo = (short) bp->b_bcount; 21547e911b15Skarels dga->bytcnt_hi = (short) (bp->b_bcount >> 16); 21557e911b15Skarels 21567e911b15Skarels while (qdflags[unit].user_dma) { 21577e911b15Skarels sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); 21587e911b15Skarels } 21597e911b15Skarels 21607e911b15Skarels splx(s); 21617e911b15Skarels ubarelse(0, &QBAreg); 21627e911b15Skarels 21637e911b15Skarels if (!(dga->csr & DMA_ERR)) { 21647e911b15Skarels iodone(bp); 21657e911b15Skarels return; 21667e911b15Skarels } 21677e911b15Skarels 21687e911b15Skarels STRAT_ERR: 21697e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 21707e911b15Skarels adder->command = CANCEL; /* cancel adder activity */ 21717e911b15Skarels dga->csr &= ~DMA_IE; 21727e911b15Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 21737e911b15Skarels dga->csr |= DMA_ERR; /* clear error condition */ 21747e911b15Skarels bp->b_flags |= B_ERROR; /* flag an error to physio() */ 21757e911b15Skarels 21767e911b15Skarels /* if DMA was running, flush spurious intrpt */ 21777e911b15Skarels 21787e911b15Skarels if (dga->bytcnt_lo != 0) { 21797e911b15Skarels dga->bytcnt_lo = 0; 21807e911b15Skarels dga->bytcnt_hi = 0; 21817e911b15Skarels DMA_SETIGNORE(DMAheader[unit]); 21827e911b15Skarels dga->csr |= DMA_IE; 21837e911b15Skarels } 21847e911b15Skarels 21857e911b15Skarels iodone(bp); 21867e911b15Skarels 21877e911b15Skarels } /* qd_strategy */ 21887e911b15Skarels 21897e911b15Skarels /******************************************************************* 21907e911b15Skarels * 21917e911b15Skarels * qdstart()... startup output to the console screen 21927e911b15Skarels * 21937e911b15Skarels ******************************************************************** 21947e911b15Skarels * 21957e911b15Skarels * calling convention: 21967e911b15Skarels * 21977e911b15Skarels * qdstart(tp); 2198*e977faadSmarc * struct tty *tp; ;pointer to tty structure 21997e911b15Skarels * 22007e911b15Skarels ********/ 22017e911b15Skarels 22027e911b15Skarels qdstart(tp) 22037e911b15Skarels register struct tty *tp; 22047e911b15Skarels { 22057e911b15Skarels register int which_unit, unit, c; 2206*e977faadSmarc register struct tty *tp0; 22077e911b15Skarels int s; 22087e911b15Skarels 2209*e977faadSmarc int curs_on; 2210*e977faadSmarc struct dga *dga; 22117e911b15Skarels 2212*e977faadSmarc unit = minor(tp->t_dev); 2213*e977faadSmarc 2214*e977faadSmarc tp0 = &qd_tty[(unit & 0x0FC)+1]; 2215*e977faadSmarc which_unit = (unit >> 2) & 0x3; 2216*e977faadSmarc unit &= 0x03; 2217*e977faadSmarc 2218*e977faadSmarc s = spl5(); 2219*e977faadSmarc 2220*e977faadSmarc /*------------------------------------------------------------------ 2221*e977faadSmarc * If it's currently active, or delaying, no need to do anything. */ 2222*e977faadSmarc 22237e911b15Skarels if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 22247e911b15Skarels goto out; 22257e911b15Skarels 2226*e977faadSmarc /*------------------------------------------------------------------- 2227*e977faadSmarc * Display chars until the queue is empty, if the alternate console device 2228*e977faadSmarc * is open direct chars there. Drop input from anything but the console 2229*e977faadSmarc * device on the floor. */ 2230*e977faadSmarc /* TANDEM is set on the second subchannel for flow control. */ 2231*e977faadSmarc 22327e911b15Skarels while ( tp->t_outq.c_cc ) { 22337e911b15Skarels c = getc(&tp->t_outq); 2234*e977faadSmarc if (unit == 0) 2235*e977faadSmarc blitc(which_unit, (char)(c & 0xFF)); 2236*e977faadSmarc #ifdef notdef /* never never never */ 2237*e977faadSmarc if (unit == 0) { /* console device */ 2238*e977faadSmarc if (tp0->t_state & TS_ISOPEN) { 2239*e977faadSmarc if (tp0->t_state & TS_TBLOCK) 2240*e977faadSmarc goto out; 2241*e977faadSmarc c = getc(&tp->t_outq); 2242*e977faadSmarc (*linesw[tp0->t_line].l_rint)(c, tp0); 2243*e977faadSmarc } else { 2244*e977faadSmarc c = getc(&tp->t_outq); 2245*e977faadSmarc blitc(which_unit, (char)(c & 0xFF)); 22467e911b15Skarels } 2247*e977faadSmarc } else if (unit == 1) { /* qconsole, do flow control */ 2248*e977faadSmarc c = getc(&tp->t_outq); 2249*e977faadSmarc if ((tp0->t_state&TS_TBLOCK) == 0) { 2250*e977faadSmarc tp = &qd_tty[0]; 2251*e977faadSmarc unit = minor(tp->t_dev); 2252*e977faadSmarc unit &= 0x03; 2253*e977faadSmarc continue; 2254*e977faadSmarc } else 2255*e977faadSmarc goto out; 2256*e977faadSmarc } else 2257*e977faadSmarc c = getc(&tp->t_outq); 2258*e977faadSmarc #endif 2259*e977faadSmarc } 2260*e977faadSmarc 2261*e977faadSmarc /*-------------------------------------------------------- 2262*e977faadSmarc * If there are sleepers, and output has drained below low 2263*e977faadSmarc * water mark, wake up the sleepers. */ 2264*e977faadSmarc 2265*e977faadSmarc if ( tp->t_outq.c_cc <= TTLOWAT(tp) ) { 22667e911b15Skarels if (tp->t_state & TS_ASLEEP){ 22677e911b15Skarels tp->t_state &= ~TS_ASLEEP; 22687e911b15Skarels wakeup((caddr_t) &tp->t_outq); 22697e911b15Skarels } 2270*e977faadSmarc } 2271*e977faadSmarc 2272*e977faadSmarc tp->t_state &= ~TS_BUSY; 22737e911b15Skarels 22747e911b15Skarels out: 22757e911b15Skarels splx(s); 22767e911b15Skarels 22777e911b15Skarels } /* qdstart */ 22787e911b15Skarels 22797e911b15Skarels 22807e911b15Skarels /******************************************************************* 22817e911b15Skarels * 22827e911b15Skarels * qdstop()... stop the tty 22837e911b15Skarels * 22847e911b15Skarels *******************************************************************/ 22857e911b15Skarels 22867e911b15Skarels qdstop(tp, flag) 22877e911b15Skarels register struct tty *tp; 22887e911b15Skarels int flag; 22897e911b15Skarels { 22907e911b15Skarels register int s; 22917e911b15Skarels 2292*e977faadSmarc s = spl5(); /* block intrpts during state modification */ 2293*e977faadSmarc 22947e911b15Skarels if (tp->t_state & TS_BUSY) { 22957e911b15Skarels if ((tp->t_state & TS_TTSTOP) == 0) { 22967e911b15Skarels tp->t_state |= TS_FLUSH; 22977e911b15Skarels } else 22987e911b15Skarels tp->t_state &= ~TS_BUSY; 22997e911b15Skarels } 23007e911b15Skarels splx(s); 23017e911b15Skarels } 23027e911b15Skarels 23037e911b15Skarels /******************************************************************* 23047e911b15Skarels * 23057e911b15Skarels * blitc()... output a character to the QDSS screen 23067e911b15Skarels * 23077e911b15Skarels ******************************************************************** 23087e911b15Skarels * 23097e911b15Skarels * calling convention: 23107e911b15Skarels * 23117e911b15Skarels * blitc(chr); 23127e911b15Skarels * char chr; ;character to be displayed 23137e911b15Skarels * 23147e911b15Skarels ********/ 23157e911b15Skarels 23167e911b15Skarels blitc(unit, chr) 23177e911b15Skarels int unit; 2318*e977faadSmarc unsigned char chr; 23197e911b15Skarels { 23207e911b15Skarels register struct adder *adder; 23217e911b15Skarels register struct dga *dga; 23227e911b15Skarels register int i; 23237e911b15Skarels 23247e911b15Skarels short x; 2325*e977faadSmarc unsigned char savechar; 23267e911b15Skarels 2327*e977faadSmarc /*--------------- 2328*e977faadSmarc * init stuff */ 23297e911b15Skarels 23307e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 23317e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 23327e911b15Skarels 2333*e977faadSmarc /*--------------------------- 2334*e977faadSmarc * non display character? */ 23357e911b15Skarels 2336*e977faadSmarc chr &= 0xFF; 233724f67f6bSmarc 23387e911b15Skarels switch (chr) { 23397e911b15Skarels 23407e911b15Skarels case '\r': /* return char */ 23417e911b15Skarels cursor[unit].x = 0; 2342*e977faadSmarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 23437e911b15Skarels dga->x_cursor = TRANX(cursor[unit].x); 23447e911b15Skarels return(0); 23457e911b15Skarels 23467e911b15Skarels case '\t': /* tab char */ 23477e911b15Skarels 23487e911b15Skarels for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) { 23497e911b15Skarels blitc(unit, ' '); 23507e911b15Skarels } 23517e911b15Skarels return(0); 23527e911b15Skarels 23537e911b15Skarels case '\n': /* line feed char */ 23547e911b15Skarels 23557e911b15Skarels if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { 23567e911b15Skarels if (qdflags[unit].inuse & GRAPHIC_DEV) { 23577e911b15Skarels cursor[unit].y = 0; 23587e911b15Skarels } else { 23597e911b15Skarels cursor[unit].y -= CHAR_HEIGHT; 23607e911b15Skarels scroll_up(adder); 23617e911b15Skarels } 23627e911b15Skarels } 2363*e977faadSmarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 23647e911b15Skarels dga->y_cursor = TRANY(cursor[unit].y); 23657e911b15Skarels return(0); 23667e911b15Skarels 23677e911b15Skarels case '\b': /* backspace char */ 23687e911b15Skarels if (cursor[unit].x > 0) { 23697e911b15Skarels cursor[unit].x -= CHAR_WIDTH; 2370*e977faadSmarc blitc(unit, ' '); 2371*e977faadSmarc cursor[unit].x -= CHAR_WIDTH; 2372*e977faadSmarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 23737e911b15Skarels dga->x_cursor = TRANX(cursor[unit].x); 23747e911b15Skarels } 23757e911b15Skarels return(0); 23767e911b15Skarels 23777e911b15Skarels default: 2378*e977faadSmarc /*---------------------------------------------------------- 2379*e977faadSmarc * Weed out unprintable characters. Printable characters fall 2380*e977faadSmarc * between space (0x20) and tilde (0x7E). For 8-bit support 2381*e977faadSmarc * another range of printable characters are those between 2382*e977faadSmarc * 0xA1 and 0xFD. */ 2383*e977faadSmarc 2384*e977faadSmarc if ((chr < ' ') || (chr > 0xFD) || (chr < 0xA1 && chr > '~')) 23857e911b15Skarels return(0); 23867e911b15Skarels } 23877e911b15Skarels 2388*e977faadSmarc /*------------------------------------------ 2389*e977faadSmarc * setup VIPER operand control registers */ 23907e911b15Skarels 23917e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ 23927e911b15Skarels write_ID(adder, SRC1_OCR_B, 23937e911b15Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 23947e911b15Skarels 23957e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ 23967e911b15Skarels write_ID(adder, SRC1_OCR_B, 23977e911b15Skarels EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); 23987e911b15Skarels 23997e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 24007e911b15Skarels write_ID(adder, DST_OCR_B, 24017e911b15Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 24027e911b15Skarels 24037e911b15Skarels write_ID(adder, MASK_1, 0xFFFF); 24047e911b15Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); 24057e911b15Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 24067e911b15Skarels 2407*e977faadSmarc adder->x_clip_min = 0; 2408*e977faadSmarc adder->x_clip_max = 1024; 2409*e977faadSmarc adder->y_clip_min = 0; 2410*e977faadSmarc adder->y_clip_max = 864; 2411*e977faadSmarc 2412*e977faadSmarc /*---------------------------------------- 2413*e977faadSmarc * load DESTINATION origin and vectors */ 24147e911b15Skarels 24157e911b15Skarels adder->fast_dest_dy = 0; 24167e911b15Skarels adder->slow_dest_dx = 0; 24177e911b15Skarels adder->error_1 = 0; 24187e911b15Skarels adder->error_2 = 0; 24197e911b15Skarels 24207e911b15Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 24217e911b15Skarels 24227e911b15Skarels wait_status(adder, RASTEROP_COMPLETE); 24237e911b15Skarels 24247e911b15Skarels adder->destination_x = cursor[unit].x; 24257e911b15Skarels adder->fast_dest_dx = CHAR_WIDTH; 24267e911b15Skarels 24277e911b15Skarels adder->destination_y = cursor[unit].y; 24287e911b15Skarels adder->slow_dest_dy = CHAR_HEIGHT; 24297e911b15Skarels 2430*e977faadSmarc /*----------------------------------- 2431*e977faadSmarc * load SOURCE origin and vectors */ 24327e911b15Skarels 2433*e977faadSmarc if (chr > '~') { 2434*e977faadSmarc savechar = chr; 2435*e977faadSmarc chr -= 34; /* These are to skip the (32) 8-bit control chars. 2436*e977faadSmarc as well as DEL and 0xA0 which aren't printable */ 2437*e977faadSmarc } 2438*e977faadSmarc if ((chr - ' ') > (CHARS - 1)) { 2439*e977faadSmarc printf("Invalid character (x)%x in blitc\n",chr); 2440*e977faadSmarc chr = ' '; 2441*e977faadSmarc } 2442*e977faadSmarc /* X position is modulo the number of characters per line */ 2443*e977faadSmarc adder->source_1_x = FONT_X + 2444*e977faadSmarc (((chr - ' ') % (MAX_SCREEN_X/CHAR_WIDTH)) * CHAR_WIDTH); 2445*e977faadSmarc /* Point to either first or second row */ 2446*e977faadSmarc adder->source_1_y = 2048 - 15 * 2447*e977faadSmarc (((chr - ' ')/(MAX_SCREEN_X/CHAR_WIDTH)) + 1); 24487e911b15Skarels 24497e911b15Skarels adder->source_1_dx = CHAR_WIDTH; 24507e911b15Skarels adder->source_1_dy = CHAR_HEIGHT; 24517e911b15Skarels 24527e911b15Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 24537e911b15Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 24547e911b15Skarels 2455*e977faadSmarc /*------------------------------------- 2456*e977faadSmarc * update console cursor coordinates */ 24577e911b15Skarels 24587e911b15Skarels cursor[unit].x += CHAR_WIDTH; 2459*e977faadSmarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 24607e911b15Skarels dga->x_cursor = TRANX(cursor[unit].x); 24617e911b15Skarels 24627e911b15Skarels if (cursor[unit].x > (1024 - CHAR_WIDTH)) { 24637e911b15Skarels blitc(unit, '\r'); 24647e911b15Skarels blitc(unit, '\n'); 24657e911b15Skarels } 24667e911b15Skarels 24677e911b15Skarels } /* blitc */ 24687e911b15Skarels 24697e911b15Skarels qdreset(){} 24707e911b15Skarels qd_init(){} 24717e911b15Skarels 24727e911b15Skarels /****************************************************************** 2473*e977faadSmarc ******************************************************************* 2474*e977faadSmarc ******************************************************************* 24757e911b15Skarels * 24767e911b15Skarels * INTERRUPT SERVICE ROUTINES START HERE: 24777e911b15Skarels * 2478*e977faadSmarc ******************************************************************* 2479*e977faadSmarc ******************************************************************* 24807e911b15Skarels ******************************************************************/ 24817e911b15Skarels 24827e911b15Skarels /***************************************************************** 24837e911b15Skarels * 24847e911b15Skarels * qddint()... service "DMA DONE" interrupt condition 24857e911b15Skarels * 24867e911b15Skarels *****************************************************************/ 24877e911b15Skarels 24887e911b15Skarels qddint(qd) 24897e911b15Skarels int qd; 24907e911b15Skarels { 24917e911b15Skarels register struct DMAreq_header *header; 24927e911b15Skarels register struct DMAreq *request; 24937e911b15Skarels register struct dga *dga; 24947e911b15Skarels struct adder *adder; 24957e911b15Skarels 24967e911b15Skarels int cookie; /* DMA adrs for QDSS */ 24977e911b15Skarels int i; 24987e911b15Skarels 24997e911b15Skarels spl4(); /* allow interval timer in */ 25007e911b15Skarels 2501*e977faadSmarc /*----------------- 2502*e977faadSmarc * init pointers */ 25037e911b15Skarels 25047e911b15Skarels header = DMAheader[qd]; /* register for optimization */ 25057e911b15Skarels dga = (struct dga *) qdmap[qd].dga; 25067e911b15Skarels adder = (struct adder *) qdmap[qd].adder; 25077e911b15Skarels 2508*e977faadSmarc /*------------------------------------------------------------------------ 2509*e977faadSmarc * if this interrupt flagged as bogus for interrupt flushing purposes.. */ 25107e911b15Skarels 25117e911b15Skarels if (DMA_ISIGNORE(header)) { 25127e911b15Skarels DMA_CLRIGNORE(header); 25137e911b15Skarels return; 25147e911b15Skarels } 25157e911b15Skarels 25167e911b15Skarels /*---------------------------------------------------- 25177e911b15Skarels * dump a DMA hardware error message if appropriate */ 25187e911b15Skarels 25197e911b15Skarels if (dga->csr & DMA_ERR) { 25207e911b15Skarels 25217e911b15Skarels if (dga->csr & PARITY_ERR) 2522*e977faadSmarc printf("\nqd%d: qddint: DMA hardware parity fault.", qd); 25237e911b15Skarels 25247e911b15Skarels if (dga->csr & BUS_ERR) 2525*e977faadSmarc printf("\nqd%d: qddint: DMA hardware bus error.", qd); 25267e911b15Skarels } 25277e911b15Skarels 25287e911b15Skarels /*---------------------------------------- 25297e911b15Skarels * if this was a DMA from user space... */ 25307e911b15Skarels 25317e911b15Skarels if (qdflags[qd].user_dma) { 25327e911b15Skarels qdflags[qd].user_dma = 0; 25337e911b15Skarels wakeup((caddr_t)&qdflags[qd].user_dma); 25347e911b15Skarels return; 25357e911b15Skarels } 25367e911b15Skarels 25377e911b15Skarels /*------------------------------------------------------------------------ 25387e911b15Skarels * if we're doing DMA request queue services, field the error condition */ 25397e911b15Skarels 25407e911b15Skarels if (dga->csr & DMA_ERR) { 25417e911b15Skarels 25427e911b15Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 25437e911b15Skarels dga->csr |= DMA_ERR; /* clear error condition */ 25447e911b15Skarels adder->command = CANCEL; /* cancel adder activity */ 25457e911b15Skarels 25467e911b15Skarels DMA_SETERROR(header); /* flag error in header status word */ 25477e911b15Skarels DMA_CLRACTIVE(header); 25487e911b15Skarels header->DMAreq[header->oldest].DMAdone |= HARD_ERROR; 25497e911b15Skarels header->newest = header->oldest; 25507e911b15Skarels header->used = 0; 25517e911b15Skarels 25527e911b15Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 25537e911b15Skarels selwakeup(rsel[qd], 0); 25547e911b15Skarels rsel[qd] = 0; 25557e911b15Skarels qdflags[qd].selmask &= ~SEL_WRITE; 25567e911b15Skarels } 25577e911b15Skarels 25587e911b15Skarels if (dga->bytcnt_lo != 0) { 25597e911b15Skarels dga->bytcnt_lo = 0; 25607e911b15Skarels dga->bytcnt_hi = 0; 25617e911b15Skarels DMA_SETIGNORE(header); 25627e911b15Skarels } 25637e911b15Skarels 25647e911b15Skarels return; 25657e911b15Skarels } 25667e911b15Skarels 25677e911b15Skarels /*---------------------------------------------------------------------------- 25687e911b15Skarels * if the DMA request queue is now becoming non-full, wakeup "select" client */ 25697e911b15Skarels 25707e911b15Skarels if (DMA_ISFULL(header)) { 25717e911b15Skarels 25727e911b15Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 25737e911b15Skarels selwakeup(rsel[qd], 0); 25747e911b15Skarels rsel[qd] = 0; 25757e911b15Skarels qdflags[qd].selmask &= ~SEL_WRITE; 25767e911b15Skarels } 25777e911b15Skarels } 25787e911b15Skarels 25797e911b15Skarels header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE; 2580*e977faadSmarc QDlast_DMAtype = header->DMAreq[header->oldest].DMAtype; 25817e911b15Skarels 2582*e977faadSmarc /* check for unexpected interrupt */ 2583*e977faadSmarc if (DMA_ISEMPTY(header)) 25847e911b15Skarels return; 25857e911b15Skarels 25867e911b15Skarels DMA_GETEND(header); /* update request queue indices */ 25877e911b15Skarels 25887e911b15Skarels /*------------------------------------------------------------ 25897e911b15Skarels * if no more DMA pending, wake up "select" client and exit */ 25907e911b15Skarels 25917e911b15Skarels if (DMA_ISEMPTY(header)) { 25927e911b15Skarels 25937e911b15Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 25947e911b15Skarels selwakeup(rsel[qd], 0); 25957e911b15Skarels rsel[qd] = 0; 25967e911b15Skarels qdflags[qd].selmask &= ~SEL_WRITE; 25977e911b15Skarels } 25987e911b15Skarels 25997e911b15Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 26007e911b15Skarels return; 26017e911b15Skarels } 26027e911b15Skarels 26037e911b15Skarels /*--------------------------- 26047e911b15Skarels * initiate next DMA xfer */ 26057e911b15Skarels 26067e911b15Skarels request = DMA_GETBEGIN(header); 2607*e977faadSmarc if (request->DMAtype != QDlast_DMAtype) { 2608*e977faadSmarc dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 2609*e977faadSmarc adder->command = CANCEL; /* cancel adder activity */ 2610*e977faadSmarc } 2611*e977faadSmarc 26127e911b15Skarels 26137e911b15Skarels switch (request->DMAtype) { 26147e911b15Skarels 26157e911b15Skarels case DISPLIST: 2616*e977faadSmarc if (request->DMAtype != QDlast_DMAtype) { 26177e911b15Skarels dga->csr |= DL_ENB; 2618*e977faadSmarc dga->csr &= ~(BTOP_ENB | BYTE_DMA); 2619*e977faadSmarc } 26207e911b15Skarels break; 26217e911b15Skarels 26227e911b15Skarels case PTOB: 2623*e977faadSmarc if (request->DMAtype != QDlast_DMAtype) { 2624*e977faadSmarc if (request->DMAdone & BYTE_PACK) 2625*e977faadSmarc dga->csr |= (PTOB_ENB | BYTE_DMA); 2626*e977faadSmarc else { 26277e911b15Skarels dga->csr |= PTOB_ENB; 2628*e977faadSmarc dga->csr &= ~BYTE_DMA; 2629*e977faadSmarc } 2630*e977faadSmarc } 26317e911b15Skarels break; 26327e911b15Skarels 26337e911b15Skarels case BTOP: 2634*e977faadSmarc if (request->DMAtype != QDlast_DMAtype) { 2635*e977faadSmarc if (request->DMAdone & BYTE_PACK) { 2636*e977faadSmarc dga->csr &= ~DL_ENB; 2637*e977faadSmarc dga->csr |= (BTOP_ENB | BYTE_DMA); 2638*e977faadSmarc } 2639*e977faadSmarc else { 26407e911b15Skarels dga->csr |= BTOP_ENB; 2641*e977faadSmarc dga->csr &= ~(BYTE_DMA | DL_ENB); 2642*e977faadSmarc } 2643*e977faadSmarc } 26447e911b15Skarels break; 26457e911b15Skarels default: 2646*e977faadSmarc printf("\nqd%d: qddint: illegal DMAtype parameter.", qd); 26477e911b15Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 26487e911b15Skarels return; 26497e911b15Skarels } 26507e911b15Skarels 26517e911b15Skarels if (request->DMAdone & COUNT_ZERO) { 26527e911b15Skarels dga->csr &= ~SET_DONE_FIFO; 26537e911b15Skarels } else if (request->DMAdone & FIFO_EMPTY) { 26547e911b15Skarels dga->csr |= SET_DONE_FIFO; 26557e911b15Skarels } 26567e911b15Skarels 26577e911b15Skarels if (request->DMAdone & WORD_PACK) 26587e911b15Skarels dga->csr &= ~BYTE_DMA; 26597e911b15Skarels else if (request->DMAdone & BYTE_PACK) 26607e911b15Skarels dga->csr |= BYTE_DMA; 26617e911b15Skarels 26627e911b15Skarels dga->csr |= DMA_IE; 2663*e977faadSmarc QDlast_DMAtype = request->DMAtype; 26647e911b15Skarels 26657e911b15Skarels cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg; 26667e911b15Skarels 26677e911b15Skarels dga->adrs_lo = (short) cookie; 26687e911b15Skarels dga->adrs_hi = (short) (cookie >> 16); 26697e911b15Skarels 26707e911b15Skarels dga->bytcnt_lo = (short) request->length; 26717e911b15Skarels dga->bytcnt_hi = (short) (request->length >> 16); 26727e911b15Skarels 26737e911b15Skarels return; 26747e911b15Skarels } 26757e911b15Skarels 26767e911b15Skarels /***************************************************************** 26777e911b15Skarels * 26787e911b15Skarels * qdaint()... ADDER interrupt service 26797e911b15Skarels * 26807e911b15Skarels *****************************************************************/ 2681*e977faadSmarc int Nqdaint; 26827e911b15Skarels 26837e911b15Skarels qdaint(qd) 26847e911b15Skarels register int qd; 26857e911b15Skarels { 26867e911b15Skarels register struct adder *adder; 26877e911b15Skarels struct color_buf *cbuf; 26887e911b15Skarels 26897e911b15Skarels short stat; 26907e911b15Skarels int i; 26917e911b15Skarels register struct rgb *rgbp; 26927e911b15Skarels register short *red; 26937e911b15Skarels register short *green; 26947e911b15Skarels register short *blue; 26957e911b15Skarels 26967e911b15Skarels spl4(); /* allow interval timer in */ 2697*e977faadSmarc Nqdaint++; /* debug */ 26987e911b15Skarels 26997e911b15Skarels adder = (struct adder *) qdmap[qd].adder; 27007e911b15Skarels 27017e911b15Skarels /*------------------------------------------------------------------------ 27027e911b15Skarels * service the vertical blank interrupt (VSYNC bit) by loading any pending 27037e911b15Skarels * color map load request */ 27047e911b15Skarels 27057e911b15Skarels if (adder->status & VSYNC) { 27067e911b15Skarels adder->status &= ~VSYNC; /* clear the interrupt */ 27077e911b15Skarels 27087e911b15Skarels cbuf = color_buf[qd]; 27097e911b15Skarels if (cbuf->status & LOAD_COLOR_MAP) { 27107e911b15Skarels 27117e911b15Skarels red = (short *) qdmap[qd].red; 27127e911b15Skarels green = (short *) qdmap[qd].green; 27137e911b15Skarels blue = (short *) qdmap[qd].blue; 27147e911b15Skarels 27157e911b15Skarels for (i = cbuf->count, rgbp = cbuf->rgb; --i >= 0; rgbp++) { 27167e911b15Skarels 27177e911b15Skarels red[rgbp->offset] = (short) rgbp->red; 27187e911b15Skarels green[rgbp->offset] = (short) rgbp->green; 27197e911b15Skarels blue[rgbp->offset] = (short) rgbp->blue; 27207e911b15Skarels } 27217e911b15Skarels 27227e911b15Skarels cbuf->status &= ~LOAD_COLOR_MAP; 27237e911b15Skarels } 27247e911b15Skarels } 27257e911b15Skarels 27267e911b15Skarels /*------------------------------------------------- 27277e911b15Skarels * service the scroll interrupt (FRAME_SYNC bit) */ 27287e911b15Skarels 27297e911b15Skarels if (adder->status & FRAME_SYNC) { 27307e911b15Skarels adder->status &= ~FRAME_SYNC; /* clear the interrupt */ 27317e911b15Skarels 27327e911b15Skarels if (scroll[qd]->status & LOAD_REGS) { 27337e911b15Skarels 27347e911b15Skarels for ( i = 1000, adder->status = 0 27357e911b15Skarels ; i > 0 && !((stat = adder->status) & ID_SCROLL_READY) 27367e911b15Skarels ; --i); 27377e911b15Skarels 27387e911b15Skarels if (i == 0) { 2739*e977faadSmarc printf("\nqd%d: qdaint: timeout on ID_SCROLL_READY", qd); 27407e911b15Skarels return; 27417e911b15Skarels } 27427e911b15Skarels 27437e911b15Skarels adder->ID_scroll_data = scroll[qd]->viper_constant; 27447e911b15Skarels adder->ID_scroll_command = ID_LOAD | SCROLL_CONSTANT; 27457e911b15Skarels 27467e911b15Skarels adder->y_scroll_constant = scroll[qd]->y_scroll_constant; 27477e911b15Skarels adder->y_offset_pending = scroll[qd]->y_offset; 27487e911b15Skarels 27497e911b15Skarels if (scroll[qd]->status & LOAD_INDEX) { 27507e911b15Skarels 27517e911b15Skarels adder->x_index_pending = scroll[qd]->x_index_pending; 27527e911b15Skarels adder->y_index_pending = scroll[qd]->y_index_pending; 27537e911b15Skarels } 27547e911b15Skarels 27557e911b15Skarels scroll[qd]->status = 0x00; 27567e911b15Skarels } 27577e911b15Skarels } 27587e911b15Skarels } 27597e911b15Skarels 27607e911b15Skarels /***************************************************************** 27617e911b15Skarels * 27627e911b15Skarels * qdiint()... DUART input interrupt service routine 27637e911b15Skarels * 27647e911b15Skarels *****************************************************************/ 27657e911b15Skarels 27667e911b15Skarels qdiint(qd) 27677e911b15Skarels register int qd; 27687e911b15Skarels { 27697e911b15Skarels register struct _vs_event *event; 27707e911b15Skarels register struct qdinput *eqh; 27717e911b15Skarels 27727e911b15Skarels struct dga *dga; 27737e911b15Skarels struct duart *duart; 27747e911b15Skarels struct mouse_report *new_rep; 27757e911b15Skarels 27767e911b15Skarels struct uba_device *ui; 27777e911b15Skarels struct tty *tp; 27787e911b15Skarels 2779*e977faadSmarc u_short chr; 27807e911b15Skarels int i,j; 27817e911b15Skarels int k,l; 27827e911b15Skarels 27837e911b15Skarels u_short status; 27847e911b15Skarels u_short data; 27857e911b15Skarels u_short key; 27867e911b15Skarels 27877e911b15Skarels char do_wakeup = 0; /* flag to do a select wakeup call */ 27887e911b15Skarels char a, b, c; /* mouse button test variables */ 27897e911b15Skarels 27907e911b15Skarels spl4(); /* allow interval timer in */ 27917e911b15Skarels 27927e911b15Skarels eqh = eq_header[qd]; /* optimized as a register */ 27937e911b15Skarels new_rep = ¤t_rep[qd]; 27947e911b15Skarels duart = (struct duart *) qdmap[qd].duart; 27957e911b15Skarels 27967e911b15Skarels /*----------------------------------------- 27977e911b15Skarels * if the graphic device is turned on.. */ 27987e911b15Skarels 27997e911b15Skarels if (qdflags[qd].inuse & GRAPHIC_DEV) { 28007e911b15Skarels 28017e911b15Skarels /*--------------- 28027e911b15Skarels * empty DUART */ 28037e911b15Skarels 28047e911b15Skarels while ((status = duart->statusA) & RCV_RDY || 28057e911b15Skarels (status = duart->statusB) & RCV_RDY) { 28067e911b15Skarels 28077e911b15Skarels /*--------------------------------- 28087e911b15Skarels * pick up LK-201 input (if any) */ 28097e911b15Skarels 28107e911b15Skarels if ((status = duart->statusA) & RCV_RDY) { 28117e911b15Skarels 28127e911b15Skarels /* if error condition, then reset it */ 28137e911b15Skarels 28147e911b15Skarels if ((status = duart->statusA) & 0x70) { 28157e911b15Skarels duart->cmdA = 0x40; 28167e911b15Skarels continue; 28177e911b15Skarels } 28187e911b15Skarels 28197e911b15Skarels /* event queue full now? (overflow condition) */ 28207e911b15Skarels 28217e911b15Skarels if (ISFULL(eqh) == TRUE) { 2822*e977faadSmarc printf("\nqd%d: qdiint: event queue overflow", qd); 28237e911b15Skarels break; 28247e911b15Skarels } 28257e911b15Skarels 28267e911b15Skarels /*-------------------------------------- 28277e911b15Skarels * Check for various keyboard errors */ 28287e911b15Skarels 28297e911b15Skarels key = duart->dataA & 0xFF; 28307e911b15Skarels 28317e911b15Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 28327e911b15Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2833*e977faadSmarc printf("\nqd%d: qdiint: keyboard error, code = %x",qd,key); 28347e911b15Skarels return(0); 28357e911b15Skarels } 28367e911b15Skarels 28377e911b15Skarels if (key < LK_LOWEST) 28387e911b15Skarels return(0); 28397e911b15Skarels 28407e911b15Skarels ++do_wakeup; /* request a select wakeup call */ 28417e911b15Skarels 28427e911b15Skarels event = PUTBEGIN(eqh); 28437e911b15Skarels PUTEND(eqh); 28447e911b15Skarels 28457e911b15Skarels event->vse_key = key; 28467e911b15Skarels event->vse_key &= 0x00FF; 28477e911b15Skarels event->vse_x = eqh->curs_pos.x; 28487e911b15Skarels event->vse_y = eqh->curs_pos.y; 28497e911b15Skarels event->vse_time = TOY; 28507e911b15Skarels event->vse_type = VSE_BUTTON; 28517e911b15Skarels event->vse_direction = VSE_KBTRAW; 28527e911b15Skarels event->vse_device = VSE_DKB; 28537e911b15Skarels } 28547e911b15Skarels 28557e911b15Skarels /*------------------------------------- 28567e911b15Skarels * pick up the mouse input (if any) */ 28577e911b15Skarels 28587e911b15Skarels if ((status = duart->statusB) & RCV_RDY && 28597e911b15Skarels qdflags[qd].pntr_id == MOUSE_ID) { 28607e911b15Skarels 28617e911b15Skarels if (status & 0x70) { 28627e911b15Skarels duart->cmdB = 0x40; 28637e911b15Skarels continue; 28647e911b15Skarels } 28657e911b15Skarels 28667e911b15Skarels /* event queue full now? (overflow condition) */ 28677e911b15Skarels 28687e911b15Skarels if (ISFULL(eqh) == TRUE) { 2869*e977faadSmarc printf("\nqd%d: qdiint: event queue overflow", qd); 28707e911b15Skarels break; 28717e911b15Skarels } 28727e911b15Skarels 28737e911b15Skarels data = duart->dataB; /* get report byte */ 28747e911b15Skarels ++new_rep->bytcnt; /* bump report byte count */ 28757e911b15Skarels 28767e911b15Skarels /*--------------------------- 28777e911b15Skarels * if 1st byte of report.. */ 28787e911b15Skarels 28797e911b15Skarels if ( data & START_FRAME) { 28807e911b15Skarels new_rep->state = data; 28817e911b15Skarels if (new_rep->bytcnt > 1) { 28827e911b15Skarels new_rep->bytcnt = 1; /* start of new frame */ 28837e911b15Skarels continue; /* ..continue looking */ 28847e911b15Skarels } 28857e911b15Skarels } 28867e911b15Skarels 28877e911b15Skarels /*--------------------------- 28887e911b15Skarels * if 2nd byte of report.. */ 28897e911b15Skarels 28907e911b15Skarels else if (new_rep->bytcnt == 2) { 28917e911b15Skarels new_rep->dx = data & 0x00FF; 28927e911b15Skarels } 28937e911b15Skarels 28947e911b15Skarels /*------------------------------------------------- 28957e911b15Skarels * if 3rd byte of report, load input event queue */ 28967e911b15Skarels 28977e911b15Skarels else if (new_rep->bytcnt == 3) { 28987e911b15Skarels 28997e911b15Skarels new_rep->dy = data & 0x00FF; 29007e911b15Skarels new_rep->bytcnt = 0; 29017e911b15Skarels 29027e911b15Skarels /*----------------------------------- 29037e911b15Skarels * if mouse position has changed.. */ 29047e911b15Skarels 29057e911b15Skarels if (new_rep->dx != 0 || new_rep->dy != 0) { 29067e911b15Skarels 29077e911b15Skarels /*--------------------------------------------- 29087e911b15Skarels * calculate acceleration factor, if needed */ 29097e911b15Skarels 29107e911b15Skarels if (qdflags[qd].curs_acc > ACC_OFF) { 29117e911b15Skarels 29127e911b15Skarels if (qdflags[qd].curs_thr <= new_rep->dx) 29137e911b15Skarels new_rep->dx += 29147e911b15Skarels (new_rep->dx - qdflags[qd].curs_thr) 29157e911b15Skarels * qdflags[qd].curs_acc; 29167e911b15Skarels 29177e911b15Skarels if (qdflags[qd].curs_thr <= new_rep->dy) 29187e911b15Skarels new_rep->dy += 29197e911b15Skarels (new_rep->dy - qdflags[qd].curs_thr) 29207e911b15Skarels * qdflags[qd].curs_acc; 29217e911b15Skarels } 29227e911b15Skarels 29237e911b15Skarels /*------------------------------------- 29247e911b15Skarels * update cursor position coordinates */ 29257e911b15Skarels 29267e911b15Skarels if (new_rep->state & X_SIGN) { 29277e911b15Skarels eqh->curs_pos.x += new_rep->dx; 29287e911b15Skarels if (eqh->curs_pos.x > 1023) 29297e911b15Skarels eqh->curs_pos.x = 1023; 29307e911b15Skarels } 29317e911b15Skarels else { 29327e911b15Skarels eqh->curs_pos.x -= new_rep->dx; 29337e911b15Skarels if (eqh->curs_pos.x < -15) 29347e911b15Skarels eqh->curs_pos.x = -15; 29357e911b15Skarels } 29367e911b15Skarels 29377e911b15Skarels if (new_rep->state & Y_SIGN) { 29387e911b15Skarels eqh->curs_pos.y -= new_rep->dy; 29397e911b15Skarels if (eqh->curs_pos.y < -15) 29407e911b15Skarels eqh->curs_pos.y = -15; 29417e911b15Skarels } 29427e911b15Skarels else { 29437e911b15Skarels eqh->curs_pos.y += new_rep->dy; 29447e911b15Skarels if (eqh->curs_pos.y > 863) 29457e911b15Skarels eqh->curs_pos.y = 863; 29467e911b15Skarels } 29477e911b15Skarels 29487e911b15Skarels /*--------------------------------- 29497e911b15Skarels * update cursor screen position */ 29507e911b15Skarels 29517e911b15Skarels dga = (struct dga *) qdmap[qd].dga; 29527e911b15Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 29537e911b15Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 29547e911b15Skarels 29557e911b15Skarels /*-------------------------------------------- 29567e911b15Skarels * if cursor is in the box, no event report */ 29577e911b15Skarels 29587e911b15Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 29597e911b15Skarels eqh->curs_pos.x >= eqh->curs_box.left && 29607e911b15Skarels eqh->curs_pos.y >= eqh->curs_box.top && 29617e911b15Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 29627e911b15Skarels goto GET_MBUTTON; 29637e911b15Skarels } 29647e911b15Skarels 29657e911b15Skarels /*--------------------------------- 29667e911b15Skarels * report the mouse motion event */ 29677e911b15Skarels 29687e911b15Skarels event = PUTBEGIN(eqh); 29697e911b15Skarels PUTEND(eqh); 29707e911b15Skarels 29717e911b15Skarels ++do_wakeup; /* request a select wakeup call */ 29727e911b15Skarels 29737e911b15Skarels event->vse_x = eqh->curs_pos.x; 29747e911b15Skarels event->vse_y = eqh->curs_pos.y; 29757e911b15Skarels 29767e911b15Skarels event->vse_device = VSE_MOUSE; /* mouse */ 29777e911b15Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 29787e911b15Skarels event->vse_key = 0; 29797e911b15Skarels event->vse_direction = 0; 29807e911b15Skarels event->vse_time = TOY; /* time stamp */ 29817e911b15Skarels } 29827e911b15Skarels 29837e911b15Skarels GET_MBUTTON: 29847e911b15Skarels /*------------------------------- 29857e911b15Skarels * if button state has changed */ 29867e911b15Skarels 29877e911b15Skarels a = new_rep->state & 0x07; /*mask nonbutton bits */ 29887e911b15Skarels b = last_rep[qd].state & 0x07; 29897e911b15Skarels 29907e911b15Skarels if (a ^ b) { 29917e911b15Skarels 29927e911b15Skarels for ( c = 1; c < 8; c <<= 1) { 29937e911b15Skarels 29947e911b15Skarels if (!( c & (a ^ b))) /* this button change? */ 29957e911b15Skarels continue; 29967e911b15Skarels 29977e911b15Skarels /* event queue full? (overflow condition) */ 29987e911b15Skarels 29997e911b15Skarels if (ISFULL(eqh) == TRUE) { 3000*e977faadSmarc printf("\nqd%d: qdiint: event queue overflow", qd); 30017e911b15Skarels break; 30027e911b15Skarels } 30037e911b15Skarels 30047e911b15Skarels event = PUTBEGIN(eqh); /* get new event */ 30057e911b15Skarels PUTEND(eqh); 30067e911b15Skarels 30077e911b15Skarels ++do_wakeup; /* request select wakeup */ 30087e911b15Skarels 30097e911b15Skarels event->vse_x = eqh->curs_pos.x; 30107e911b15Skarels event->vse_y = eqh->curs_pos.y; 30117e911b15Skarels 30127e911b15Skarels event->vse_device = VSE_MOUSE; /* mouse */ 30137e911b15Skarels event->vse_type = VSE_BUTTON; /* new button */ 30147e911b15Skarels event->vse_time = TOY; /* time stamp */ 30157e911b15Skarels 30167e911b15Skarels /* flag changed button and if up or down */ 30177e911b15Skarels 30187e911b15Skarels if (c == RIGHT_BUTTON) 30197e911b15Skarels event->vse_key = VSE_RIGHT_BUTTON; 30207e911b15Skarels else if (c == MIDDLE_BUTTON) 30217e911b15Skarels event->vse_key = VSE_MIDDLE_BUTTON; 30227e911b15Skarels else if (c == LEFT_BUTTON) 30237e911b15Skarels event->vse_key = VSE_LEFT_BUTTON; 30247e911b15Skarels 30257e911b15Skarels /* set bit = button depressed */ 30267e911b15Skarels 30277e911b15Skarels if (c & a) 30287e911b15Skarels event->vse_direction = VSE_KBTDOWN; 30297e911b15Skarels else 30307e911b15Skarels event->vse_direction = VSE_KBTUP; 30317e911b15Skarels } 30327e911b15Skarels } 30337e911b15Skarels 30347e911b15Skarels /* refresh last report */ 30357e911b15Skarels 30367e911b15Skarels last_rep[qd] = current_rep[qd]; 30377e911b15Skarels 30387e911b15Skarels } /* get last byte of report */ 30397e911b15Skarels } /* pickup mouse input */ 30407e911b15Skarels 30417e911b15Skarels /*-------------------------------- 30427e911b15Skarels * pickup tablet input, if any */ 30437e911b15Skarels 30447e911b15Skarels else if ((status = duart->statusB) & RCV_RDY && 30457e911b15Skarels qdflags[qd].pntr_id == TABLET_ID) { 30467e911b15Skarels 30477e911b15Skarels if (status & 0x70) { 30487e911b15Skarels duart->cmdB = 0x40; 30497e911b15Skarels continue; 30507e911b15Skarels } 30517e911b15Skarels 30527e911b15Skarels /* event queue full now? (overflow condition) */ 30537e911b15Skarels 30547e911b15Skarels if (ISFULL(eqh) == TRUE) { 3055*e977faadSmarc printf("\nqd%d: qdiint: event queue overflow", qd); 30567e911b15Skarels break; 30577e911b15Skarels } 30587e911b15Skarels 30597e911b15Skarels data = duart->dataB; /* get report byte */ 30607e911b15Skarels ++new_rep->bytcnt; /* bump report byte count */ 30617e911b15Skarels 30627e911b15Skarels /*--------------------------- 30637e911b15Skarels * if 1st byte of report.. */ 30647e911b15Skarels 30657e911b15Skarels if (data & START_FRAME) { 30667e911b15Skarels new_rep->state = data; 30677e911b15Skarels if (new_rep->bytcnt > 1) { 30687e911b15Skarels new_rep->bytcnt = 1; /* start of new frame */ 30697e911b15Skarels continue; /* ..continue looking */ 30707e911b15Skarels } 30717e911b15Skarels } 30727e911b15Skarels 30737e911b15Skarels /*--------------------------- 30747e911b15Skarels * if 2nd byte of report.. */ 30757e911b15Skarels 30767e911b15Skarels else if (new_rep->bytcnt == 2) { 30777e911b15Skarels new_rep->dx = data & 0x3F; 30787e911b15Skarels } 30797e911b15Skarels 30807e911b15Skarels /*--------------------------- 30817e911b15Skarels * if 3rd byte of report.. */ 30827e911b15Skarels 30837e911b15Skarels else if (new_rep->bytcnt == 3) { 30847e911b15Skarels new_rep->dx |= (data & 0x3F) << 6; 30857e911b15Skarels } 30867e911b15Skarels 30877e911b15Skarels /*--------------------------- 30887e911b15Skarels * if 4th byte of report.. */ 30897e911b15Skarels 30907e911b15Skarels else if (new_rep->bytcnt == 4) { 30917e911b15Skarels new_rep->dy = data & 0x3F; 30927e911b15Skarels } 30937e911b15Skarels 30947e911b15Skarels /*------------------------------------------------- 30957e911b15Skarels * if 5th byte of report, load input event queue */ 30967e911b15Skarels 30977e911b15Skarels else if (new_rep->bytcnt == 5) { 30987e911b15Skarels 30997e911b15Skarels new_rep->dy |= (data & 0x3F) << 6; 31007e911b15Skarels new_rep->bytcnt = 0; 31017e911b15Skarels 31027e911b15Skarels /*------------------------------------- 31037e911b15Skarels * update cursor position coordinates */ 31047e911b15Skarels 31057e911b15Skarels new_rep->dx /= qdflags[qd].tab_res; 31067e911b15Skarels new_rep->dy = (2200 - new_rep->dy) 31077e911b15Skarels / qdflags[qd].tab_res; 31087e911b15Skarels 31097e911b15Skarels if (new_rep->dx > 1023) { 31107e911b15Skarels new_rep->dx = 1023; 31117e911b15Skarels } 31127e911b15Skarels if (new_rep->dy > 863) { 31137e911b15Skarels new_rep->dy = 863; 31147e911b15Skarels } 31157e911b15Skarels 31167e911b15Skarels /* 31177e911b15Skarels * report an event if the puck/stylus has moved 31187e911b15Skarels */ 31197e911b15Skarels 31207e911b15Skarels if (eqh->curs_pos.x != new_rep->dx || 31217e911b15Skarels eqh->curs_pos.y != new_rep->dy) { 31227e911b15Skarels 31237e911b15Skarels eqh->curs_pos.x = new_rep->dx; 31247e911b15Skarels eqh->curs_pos.y = new_rep->dy; 31257e911b15Skarels 31267e911b15Skarels /*--------------------------------- 31277e911b15Skarels * update cursor screen position */ 31287e911b15Skarels 31297e911b15Skarels dga = (struct dga *) qdmap[qd].dga; 31307e911b15Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 31317e911b15Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 31327e911b15Skarels 31337e911b15Skarels /* 31347e911b15Skarels * if cursor is in the box, no event report 31357e911b15Skarels */ 31367e911b15Skarels 31377e911b15Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 31387e911b15Skarels eqh->curs_pos.x >= eqh->curs_box.left && 31397e911b15Skarels eqh->curs_pos.y >= eqh->curs_box.top && 31407e911b15Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 31417e911b15Skarels goto GET_TBUTTON; 31427e911b15Skarels } 31437e911b15Skarels 31447e911b15Skarels /*--------------------------------- 31457e911b15Skarels * report the tablet motion event */ 31467e911b15Skarels 31477e911b15Skarels event = PUTBEGIN(eqh); 31487e911b15Skarels PUTEND(eqh); 31497e911b15Skarels 31507e911b15Skarels ++do_wakeup; /* request a select wakeup call */ 31517e911b15Skarels 31527e911b15Skarels event->vse_x = eqh->curs_pos.x; 31537e911b15Skarels event->vse_y = eqh->curs_pos.y; 31547e911b15Skarels 31557e911b15Skarels event->vse_device = VSE_TABLET; /* tablet */ 31567e911b15Skarels /* 31577e911b15Skarels * right now, X handles tablet motion the same 31587e911b15Skarels * as mouse motion 31597e911b15Skarels */ 31607e911b15Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 31617e911b15Skarels event->vse_key = 0; 31627e911b15Skarels event->vse_direction = 0; 31637e911b15Skarels event->vse_time = TOY; /* time stamp */ 31647e911b15Skarels } 31657e911b15Skarels GET_TBUTTON: 31667e911b15Skarels /*------------------------------- 31677e911b15Skarels * if button state has changed */ 31687e911b15Skarels 31697e911b15Skarels a = new_rep->state & 0x1E; /* mask nonbutton bits */ 31707e911b15Skarels b = last_rep[qd].state & 0x1E; 31717e911b15Skarels 31727e911b15Skarels if (a ^ b) { 31737e911b15Skarels 31747e911b15Skarels /* event queue full now? (overflow condition) */ 31757e911b15Skarels 31767e911b15Skarels if (ISFULL(eqh) == TRUE) { 3177*e977faadSmarc printf("\nqd%d: qdiint: event queue overflow",qd); 31787e911b15Skarels break; 31797e911b15Skarels } 31807e911b15Skarels 31817e911b15Skarels event = PUTBEGIN(eqh); /* get new event */ 31827e911b15Skarels PUTEND(eqh); 31837e911b15Skarels 31847e911b15Skarels ++do_wakeup; /* request a select wakeup call */ 31857e911b15Skarels 31867e911b15Skarels event->vse_x = eqh->curs_pos.x; 31877e911b15Skarels event->vse_y = eqh->curs_pos.y; 31887e911b15Skarels 31897e911b15Skarels event->vse_device = VSE_TABLET; /* tablet */ 31907e911b15Skarels event->vse_type = VSE_BUTTON; /* button changed */ 31917e911b15Skarels event->vse_time = TOY; /* time stamp */ 31927e911b15Skarels 31937e911b15Skarels /* define the changed button and if up or down */ 31947e911b15Skarels 31957e911b15Skarels for ( c = 1; c <= 0x10; c <<= 1) { 31967e911b15Skarels if (c & (a ^ b)) { 31977e911b15Skarels if (c == T_LEFT_BUTTON) 31987e911b15Skarels event->vse_key = VSE_T_LEFT_BUTTON; 31997e911b15Skarels else if (c == T_FRONT_BUTTON) 32007e911b15Skarels event->vse_key = VSE_T_FRONT_BUTTON; 32017e911b15Skarels else if (c == T_RIGHT_BUTTON) 32027e911b15Skarels event->vse_key = VSE_T_RIGHT_BUTTON; 32037e911b15Skarels else if (c == T_BACK_BUTTON) 32047e911b15Skarels event->vse_key = VSE_T_BACK_BUTTON; 32057e911b15Skarels break; 32067e911b15Skarels } 32077e911b15Skarels } 32087e911b15Skarels 32097e911b15Skarels /* set bit = button depressed */ 32107e911b15Skarels 32117e911b15Skarels if (c & a) 32127e911b15Skarels event->vse_direction = VSE_KBTDOWN; 32137e911b15Skarels else 32147e911b15Skarels event->vse_direction = VSE_KBTUP; 32157e911b15Skarels } 32167e911b15Skarels 32177e911b15Skarels /* refresh last report */ 32187e911b15Skarels 32197e911b15Skarels last_rep[qd] = current_rep[qd]; 32207e911b15Skarels 32217e911b15Skarels } /* get last byte of report */ 32227e911b15Skarels } /* pick up tablet input */ 32237e911b15Skarels 32247e911b15Skarels } /* while input available.. */ 32257e911b15Skarels 32267e911b15Skarels /*--------------------- 32277e911b15Skarels * do select wakeup */ 32287e911b15Skarels 3229*e977faadSmarc 32307e911b15Skarels if (rsel[qd] && do_wakeup && qdflags[qd].selmask & SEL_READ) { 32317e911b15Skarels selwakeup(rsel[qd], 0); 32327e911b15Skarels rsel[qd] = 0; 32337e911b15Skarels qdflags[qd].selmask &= ~SEL_READ; 32347e911b15Skarels do_wakeup = 0; 32357e911b15Skarels } 32367e911b15Skarels } 32377e911b15Skarels 32387e911b15Skarels /*----------------------------------------------------------------- 32397e911b15Skarels * if the graphic device is not turned on, this is console input */ 32407e911b15Skarels 32417e911b15Skarels else { 32427e911b15Skarels 32437e911b15Skarels ui = qdinfo[qd]; 32447e911b15Skarels if (ui == 0 || ui->ui_alive == 0) 32457e911b15Skarels return(0); 32467e911b15Skarels 32477e911b15Skarels tp = &qd_tty[qd << 2]; 32487e911b15Skarels 32497e911b15Skarels /*-------------------------------------- 32507e911b15Skarels * Get a character from the keyboard. */ 32517e911b15Skarels 32527e911b15Skarels while ((status = duart->statusA) & RCV_RDY) { 32537e911b15Skarels 32547e911b15Skarels key = duart->dataA; 32557e911b15Skarels key &= 0xFF; 32567e911b15Skarels 32577e911b15Skarels /*-------------------------------------- 32587e911b15Skarels * Check for various keyboard errors */ 32597e911b15Skarels 32607e911b15Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 32617e911b15Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 3262*e977faadSmarc printf("\nqd%d: qdiint: Keyboard error, code = %x",qd,key); 32637e911b15Skarels return(0); 32647e911b15Skarels } 32657e911b15Skarels 32667e911b15Skarels if (key < LK_LOWEST) 32677e911b15Skarels return(0); 32687e911b15Skarels 32697e911b15Skarels /*--------------------------------- 32707e911b15Skarels * See if its a state change key */ 32717e911b15Skarels 32727e911b15Skarels switch (key) { 32737e911b15Skarels 32747e911b15Skarels case LOCK: 32757e911b15Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 32767e911b15Skarels if (q_keyboard.lock) 32777e911b15Skarels led_control(qd, LK_LED_ENABLE, LK_LED_LOCK); 32787e911b15Skarels else 32797e911b15Skarels led_control(qd, LK_LED_DISABLE, LK_LED_LOCK); 32807e911b15Skarels return; 32817e911b15Skarels 32827e911b15Skarels case SHIFT: 32837e911b15Skarels q_keyboard.shift ^= 0xFFFF; 32847e911b15Skarels return; 32857e911b15Skarels 32867e911b15Skarels case CNTRL: 32877e911b15Skarels q_keyboard.cntrl ^= 0xFFFF; 32887e911b15Skarels return; 32897e911b15Skarels 32907e911b15Skarels case ALLUP: 32917e911b15Skarels q_keyboard.cntrl = 0; 32927e911b15Skarels q_keyboard.shift = 0; 32937e911b15Skarels return; 32947e911b15Skarels 32957e911b15Skarels case REPEAT: 32967e911b15Skarels chr = q_keyboard.last; 32977e911b15Skarels break; 32987e911b15Skarels 32997e911b15Skarels /*------------------------------------------------------- 33007e911b15Skarels * Test for cntrl characters. If set, see if the character 33017e911b15Skarels * is elligible to become a control character. */ 33027e911b15Skarels 33037e911b15Skarels default: 33047e911b15Skarels 33057e911b15Skarels if (q_keyboard.cntrl) { 33067e911b15Skarels chr = q_key[key]; 33077e911b15Skarels if (chr >= ' ' && chr <= '~') 33087e911b15Skarels chr &= 0x1F; 3309*e977faadSmarc else if (chr >= 0xA1 && chr <= 0xFE) 3310*e977faadSmarc chr &= 0x9F; 33117e911b15Skarels } 33127e911b15Skarels else if( q_keyboard.lock || q_keyboard.shift ) 33137e911b15Skarels chr = q_shift_key[key]; 33147e911b15Skarels else 33157e911b15Skarels chr = q_key[key]; 33167e911b15Skarels break; 33177e911b15Skarels } 33187e911b15Skarels 33197e911b15Skarels q_keyboard.last = chr; 33207e911b15Skarels 33217e911b15Skarels /*----------------------------------- 33227e911b15Skarels * Check for special function keys */ 33237e911b15Skarels 3324*e977faadSmarc if (chr & 0x100) { 33257e911b15Skarels char *string; 33267e911b15Skarels string = q_special[chr & 0x7F]; 33277e911b15Skarels while(*string) 33287e911b15Skarels (*linesw[tp->t_line].l_rint)(*string++, tp); 33297e911b15Skarels } 33307e911b15Skarels else { 3331*e977faadSmarc #ifdef notdef /* notneeded */ 3332*e977faadSmarc if (tp->t_iflag & ISTRIP) /* Strip to 7 bits. */ 3333*e977faadSmarc c &= 0177; 3334*e977faadSmarc else { /* Take the full 8-bits */ 3335*e977faadSmarc /* If ISTRIP is not set a valid character of 377 3336*e977faadSmarc * is read as 0377,0377 to avoid ambiguity with 3337*e977faadSmarc * the PARMARK sequence. 3338*e977faadSmarc */ 3339*e977faadSmarc if ((c == 0377) && (tp->t_line == TERMIODISC)) 3340*e977faadSmarc (*linesw[tp->t_line].l_rint)(0377,tp); 3341*e977faadSmarc 3342*e977faadSmarc } 3343*e977faadSmarc #endif /*notdef*/ 33447e911b15Skarels (*linesw[tp->t_line].l_rint)(chr, tp); 33457e911b15Skarels } 33467e911b15Skarels } 33477e911b15Skarels } 33487e911b15Skarels 3349*e977faadSmarc /*---------------------- 3350*e977faadSmarc * cleanup and exit */ 3351*e977faadSmarc 33527e911b15Skarels return(0); 33537e911b15Skarels 33547e911b15Skarels } /* qdiint */ 33557e911b15Skarels 33567e911b15Skarels /****************************************************************** 3357*e977faadSmarc ******************************************************************* 3358*e977faadSmarc ******************************************************************* 33597e911b15Skarels * 33607e911b15Skarels * THE SUBROUTINES START HERE: 33617e911b15Skarels * 33627e911b15Skarels ******************************************************************/ 33637e911b15Skarels 33647e911b15Skarels /***************************************************************** 33657e911b15Skarels * 33667e911b15Skarels * clear_qd_screen()... clear the QDSS screen 33677e911b15Skarels * 33687e911b15Skarels ****************************************************************** 33697e911b15Skarels * 33707e911b15Skarels * >>> NOTE <<< 33717e911b15Skarels * 33727e911b15Skarels * This code requires that certain adder initialization be valid. To 33737e911b15Skarels * assure that this requirement is satisfied, this routine should be 33747e911b15Skarels * called only after calling the "setup_dragon()" function. 33757e911b15Skarels * 33767e911b15Skarels * Clear the bitmap a piece at a time. Since the fast scroll clear 33777e911b15Skarels * only clears the current displayed portion of the bitmap put a 33787e911b15Skarels * temporary value in the y limit register so we can access whole 33797e911b15Skarels * bitmap 33807e911b15Skarels * 33817e911b15Skarels ****************/ 33827e911b15Skarels 33837e911b15Skarels clear_qd_screen(unit) 33847e911b15Skarels int unit; 33857e911b15Skarels { 33867e911b15Skarels register struct adder *adder; 33877e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 33887e911b15Skarels 33897e911b15Skarels adder->x_limit = 1024; 33907e911b15Skarels adder->y_limit = 2048 - CHAR_HEIGHT; 33917e911b15Skarels adder->y_offset_pending = 0; 33927e911b15Skarels 33937e911b15Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 33947e911b15Skarels wait_status(adder, VSYNC); 33957e911b15Skarels 33967e911b15Skarels adder->y_scroll_constant = SCROLL_ERASE; 33977e911b15Skarels 33987e911b15Skarels wait_status(adder, VSYNC); 33997e911b15Skarels wait_status(adder, VSYNC); 34007e911b15Skarels 34017e911b15Skarels adder->y_offset_pending = 864; 34027e911b15Skarels 34037e911b15Skarels wait_status(adder, VSYNC); 34047e911b15Skarels wait_status(adder, VSYNC); 34057e911b15Skarels 34067e911b15Skarels adder->y_scroll_constant = SCROLL_ERASE; 34077e911b15Skarels 34087e911b15Skarels wait_status(adder, VSYNC); 34097e911b15Skarels wait_status(adder, VSYNC); 34107e911b15Skarels 34117e911b15Skarels adder->y_offset_pending = 1728; 34127e911b15Skarels 34137e911b15Skarels wait_status(adder, VSYNC); 34147e911b15Skarels wait_status(adder, VSYNC); 34157e911b15Skarels 34167e911b15Skarels adder->y_scroll_constant = SCROLL_ERASE; 34177e911b15Skarels 34187e911b15Skarels wait_status(adder, VSYNC); 34197e911b15Skarels wait_status(adder, VSYNC); 34207e911b15Skarels 34217e911b15Skarels adder->y_offset_pending = 0; /* back to normal */ 34227e911b15Skarels 34237e911b15Skarels wait_status(adder, VSYNC); 34247e911b15Skarels wait_status(adder, VSYNC); 34257e911b15Skarels 34267e911b15Skarels adder->x_limit = MAX_SCREEN_X; 34277e911b15Skarels adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; 34287e911b15Skarels 34297e911b15Skarels } /* clear_qd_screen */ 34307e911b15Skarels 34317e911b15Skarels /********************************************************************** 34327e911b15Skarels * 34337e911b15Skarels * qdputc()... route kernel console output to display destination 34347e911b15Skarels * 34357e911b15Skarels *********************************************************************** 34367e911b15Skarels * 34377e911b15Skarels * calling convention: 34387e911b15Skarels * 34397e911b15Skarels * qdputc(chr); 34407e911b15Skarels * 34417e911b15Skarels * where: char chr; ;character for output 34427e911b15Skarels * 34437e911b15Skarels ****************/ 34447e911b15Skarels 34457e911b15Skarels qdputc(chr) 34467e911b15Skarels register char chr; 34477e911b15Skarels { 3448*e977faadSmarc register struct tty *tp0; 34497e911b15Skarels 3450*e977faadSmarc /*--------------------------------------------------------- 3451*e977faadSmarc * if system is now physical, forget it (ie: crash DUMP) */ 3452*e977faadSmarc 34537e911b15Skarels if ( (mfpr(MAPEN) & 1) == 0 ) 34547e911b15Skarels return; 34557e911b15Skarels 3456*e977faadSmarc /*-------------------------------------------------- 3457*e977faadSmarc * direct kernel output char to the proper place */ 3458*e977faadSmarc 3459*e977faadSmarc #ifdef notdef /* never */ 3460*e977faadSmarc tp0 = &qd_tty[1]; 3461*e977faadSmarc 3462*e977faadSmarc if (qdflags[0].kernel_loop != 0 && tp0->t_state & TS_ISOPEN) { 3463*e977faadSmarc (*linesw[tp0->t_line].l_rint)(chr, tp0); 3464*e977faadSmarc } else { 3465*e977faadSmarc blitc(0, chr & 0xff); 3466*e977faadSmarc } 3467*e977faadSmarc #endif /*notdef*/ 34687e911b15Skarels blitc(0, chr & 0xff); 346924f67f6bSmarc if ((chr & 0177) == '\n') 347024f67f6bSmarc blitc(0, '\r'); 347124f67f6bSmarc 34727e911b15Skarels 34737e911b15Skarels } /* qdputc */ 34747e911b15Skarels 34757e911b15Skarels /******************************************************************* 34767e911b15Skarels * 34777e911b15Skarels * qdgetc()... get a character from the LK201 34787e911b15Skarels * 34797e911b15Skarels ******************************************************************* 34807e911b15Skarels * 34817e911b15Skarels * calling convention: 34827e911b15Skarels * 34837e911b15Skarels * qdgetc(); 34847e911b15Skarels * 34857e911b15Skarels * returns: the character read. 34867e911b15Skarels * 34877e911b15Skarels ****************/ 34887e911b15Skarels 34897e911b15Skarels qdgetc() 34907e911b15Skarels { 34917e911b15Skarels register short key; 34927e911b15Skarels register char chr; 34937e911b15Skarels register struct duart *duart; 34947e911b15Skarels 34957e911b15Skarels u_int status; 34967e911b15Skarels 34977e911b15Skarels duart = (struct duart *) qdmap[0].duart; 34987e911b15Skarels 34997e911b15Skarels /*-------------------------------------- 35007e911b15Skarels * Get a character from the keyboard. */ 35017e911b15Skarels 35027e911b15Skarels LOOP: 35037e911b15Skarels while (!((status = duart->statusA) & RCV_RDY)) 35047e911b15Skarels ; 35057e911b15Skarels 35067e911b15Skarels key = duart->dataA; 35077e911b15Skarels key &= 0xFF; 35087e911b15Skarels 35097e911b15Skarels /*-------------------------------------- 35107e911b15Skarels * Check for various keyboard errors */ 35117e911b15Skarels 35127e911b15Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 35137e911b15Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 35147e911b15Skarels printf("Keyboard error, code = %x\n", key); 35157e911b15Skarels return(0); 35167e911b15Skarels } 35177e911b15Skarels 35187e911b15Skarels if (key < LK_LOWEST) 35197e911b15Skarels return(0); 35207e911b15Skarels 35217e911b15Skarels /*--------------------------------- 35227e911b15Skarels * See if its a state change key */ 35237e911b15Skarels 35247e911b15Skarels switch (key) { 35257e911b15Skarels 35267e911b15Skarels case LOCK: 35277e911b15Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 35287e911b15Skarels if (q_keyboard.lock) 35297e911b15Skarels led_control(LK_LED_ENABLE, LK_LED_LOCK); 35307e911b15Skarels else 35317e911b15Skarels led_control(LK_LED_DISABLE, LK_LED_LOCK); 35327e911b15Skarels goto LOOP; 35337e911b15Skarels 35347e911b15Skarels case SHIFT: 35357e911b15Skarels q_keyboard.shift ^= 0xFFFF; 35367e911b15Skarels goto LOOP; 35377e911b15Skarels 35387e911b15Skarels case CNTRL: 35397e911b15Skarels q_keyboard.cntrl ^= 0xFFFF; 35407e911b15Skarels goto LOOP; 35417e911b15Skarels 35427e911b15Skarels case ALLUP: 35437e911b15Skarels q_keyboard.cntrl = 0; 35447e911b15Skarels q_keyboard.shift = 0; 35457e911b15Skarels goto LOOP; 35467e911b15Skarels 35477e911b15Skarels case REPEAT: 35487e911b15Skarels chr = q_keyboard.last; 35497e911b15Skarels break; 35507e911b15Skarels 35517e911b15Skarels /*------------------------------------------------------- 35527e911b15Skarels * Test for cntrl characters. If set, see if the character 35537e911b15Skarels * is elligible to become a control character. */ 35547e911b15Skarels 35557e911b15Skarels default: 35567e911b15Skarels 35577e911b15Skarels if (q_keyboard.cntrl) { 35587e911b15Skarels chr = q_key[key]; 35597e911b15Skarels if (chr >= ' ' && chr <= '~') 35607e911b15Skarels chr &= 0x1F; 35617e911b15Skarels } 35627e911b15Skarels else if ( q_keyboard.lock || q_keyboard.shift ) 35637e911b15Skarels chr = q_shift_key[key]; 35647e911b15Skarels else 35657e911b15Skarels chr = q_key[key]; 35667e911b15Skarels break; 35677e911b15Skarels } 35687e911b15Skarels 35697e911b15Skarels if (chr < ' ' && chr > '~') /* if input is non-displayable */ 35707e911b15Skarels return(0); /* ..then pitch it! */ 35717e911b15Skarels 35727e911b15Skarels q_keyboard.last = chr; 35737e911b15Skarels 35747e911b15Skarels /*----------------------------------- 35757e911b15Skarels * Check for special function keys */ 35767e911b15Skarels 35777e911b15Skarels if (chr & 0x80) /* pitch the function keys */ 35787e911b15Skarels return(0); 35797e911b15Skarels else 35807e911b15Skarels return(chr); 35817e911b15Skarels 35827e911b15Skarels } /* qdgetc */ 35837e911b15Skarels 35847e911b15Skarels /********************************************************************** 35857e911b15Skarels * 35867e911b15Skarels * ldcursor()... load the mouse cursor's template RAM bitmap 35877e911b15Skarels * 35887e911b15Skarels ********************************************************************* 35897e911b15Skarels * 35907e911b15Skarels * calling convention: 35917e911b15Skarels * 35927e911b15Skarels * ldcursor(unit, bitmap); 35937e911b15Skarels * u_int unit; 35947e911b15Skarels * short *bitmap; 35957e911b15Skarels * 35967e911b15Skarels ****************/ 35977e911b15Skarels 35987e911b15Skarels ldcursor(unit, bitmap) 35997e911b15Skarels u_int unit; 36007e911b15Skarels short *bitmap; 36017e911b15Skarels { 36027e911b15Skarels register struct dga *dga; 36037e911b15Skarels register short *temp; 36047e911b15Skarels register int i; 36057e911b15Skarels 36067e911b15Skarels int cursor; 36077e911b15Skarels 36087e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 36097e911b15Skarels temp = (short *) qdmap[unit].template; 36107e911b15Skarels 36117e911b15Skarels if (dga->csr & CURS_ENB) { /* if the cursor is enabled.. */ 36127e911b15Skarels cursor = -1; /* ..note that.. */ 36137e911b15Skarels dga->csr &= ~CURS_ENB; /* ..and shut it off */ 36147e911b15Skarels } 36157e911b15Skarels else { 36167e911b15Skarels cursor = 0; 36177e911b15Skarels } 36187e911b15Skarels 36197e911b15Skarels dga->csr &= ~CURS_ENB; /* shut off the cursor */ 36207e911b15Skarels 36217e911b15Skarels temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ 36227e911b15Skarels /* ..of the 8k WORD template space */ 36237e911b15Skarels for (i = 0; i < 32; ++i) 36247e911b15Skarels *temp++ = *bitmap++; 36257e911b15Skarels 36267e911b15Skarels if (cursor) { /* if cursor was enabled.. */ 36277e911b15Skarels dga->csr |= CURS_ENB; /* ..turn it back on */ 36287e911b15Skarels } 36297e911b15Skarels 36307e911b15Skarels return(0); 36317e911b15Skarels 36327e911b15Skarels } /* ldcursor */ 36337e911b15Skarels 36347e911b15Skarels /********************************************************************** 36357e911b15Skarels * 36367e911b15Skarels * ldfont()... put the console font in the QDSS off-screen memory 36377e911b15Skarels * 36387e911b15Skarels *********************************************************************** 36397e911b15Skarels * 36407e911b15Skarels * calling convention: 36417e911b15Skarels * 36427e911b15Skarels * ldfont(unit); 36437e911b15Skarels * u_int unit; ;QDSS unit number 36447e911b15Skarels * 36457e911b15Skarels ****************/ 36467e911b15Skarels 36477e911b15Skarels ldfont(unit) 36487e911b15Skarels u_int unit; 36497e911b15Skarels { 36507e911b15Skarels register struct adder *adder; 36517e911b15Skarels 36527e911b15Skarels int i; /* scratch variables */ 36537e911b15Skarels int j; 36547e911b15Skarels int k; 36557e911b15Skarels short packed; 3656*e977faadSmarc int max_chars_line; 36577e911b15Skarels 36587e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 36597e911b15Skarels 36607e911b15Skarels /*------------------------------------------ 36617e911b15Skarels * setup VIPER operand control registers */ 36627e911b15Skarels 36637e911b15Skarels write_ID(adder, MASK_1, 0xFFFF); 36647e911b15Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 36657e911b15Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 36667e911b15Skarels 36677e911b15Skarels write_ID(adder, SRC1_OCR_B, 36687e911b15Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 36697e911b15Skarels write_ID(adder, SRC2_OCR_B, 36707e911b15Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 36717e911b15Skarels write_ID(adder, DST_OCR_B, 36727e911b15Skarels EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 36737e911b15Skarels 36747e911b15Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 36757e911b15Skarels 36767e911b15Skarels /*-------------------------- 36777e911b15Skarels * load destination data */ 36787e911b15Skarels 36797e911b15Skarels wait_status(adder, RASTEROP_COMPLETE); 36807e911b15Skarels 36817e911b15Skarels adder->destination_x = FONT_X; 36827e911b15Skarels adder->destination_y = FONT_Y; 3683*e977faadSmarc if (FONT_WIDTH > MAX_SCREEN_X) 3684*e977faadSmarc adder->fast_dest_dx = MAX_SCREEN_X; 3685*e977faadSmarc else 36867e911b15Skarels adder->fast_dest_dx = FONT_WIDTH; 36877e911b15Skarels adder->slow_dest_dy = CHAR_HEIGHT; 36887e911b15Skarels 36897e911b15Skarels /*--------------------------------------- 36907e911b15Skarels * setup for processor to bitmap xfer */ 36917e911b15Skarels 36927e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 36937e911b15Skarels adder->cmd = PBT | OCRB | 2 | DTE | 2; 36947e911b15Skarels 3695*e977faadSmarc /*--------------------------------------- 3696*e977faadSmarc * Figure out how many characters can be stored on one "line" of offscreen memory 3697*e977faadSmarc */ 3698*e977faadSmarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3699*e977faadSmarc if ((CHARS/2 + CHARS%2) < max_chars_line) 3700*e977faadSmarc max_chars_line = CHARS/2 + CHARS%2; 3701*e977faadSmarc 3702*e977faadSmarc /*----------------------------------------------- 3703*e977faadSmarc * iteratively do the processor to bitmap xfer */ 3704*e977faadSmarc 3705*e977faadSmarc for (i = 0; i < ROWS; ++i) { 3706*e977faadSmarc 3707*e977faadSmarc /* PTOB a scan line */ 3708*e977faadSmarc 3709*e977faadSmarc for (j = 0, k = i; j < max_chars_line; ++j) { 3710*e977faadSmarc /* PTOB one scan of a char cell */ 3711*e977faadSmarc 3712*e977faadSmarc packed = q_font[k]; 3713*e977faadSmarc k += ROWS; 3714*e977faadSmarc packed |= ((short)q_font[k] << 8); 3715*e977faadSmarc k += ROWS; 3716*e977faadSmarc 3717*e977faadSmarc wait_status(adder, TX_READY); 3718*e977faadSmarc adder->id_data = packed; 3719*e977faadSmarc } 3720*e977faadSmarc } 3721*e977faadSmarc 3722*e977faadSmarc /*--------------------------------------- 3723*e977faadSmarc * Copy the second row of characters. 3724*e977faadSmarc * Subtract the first row from the total number. Divide this quantity by 2 3725*e977faadSmarc * because 2 chars are stored in a short in the PTOB loop below. 3726*e977faadSmarc * Figure out how many characters can be stored on one "line" of offscreen memory 3727*e977faadSmarc */ 3728*e977faadSmarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3729*e977faadSmarc if ((CHARS/2 + CHARS%2) < max_chars_line) 3730*e977faadSmarc return; 3731*e977faadSmarc max_chars_line = (CHARS/2 + CHARS%2) - max_chars_line; /* 95 - 64 */ 3732*e977faadSmarc /* Paranoia check to see if 3rd row may be needed */ 3733*e977faadSmarc if (max_chars_line > (MAX_SCREEN_X/(CHAR_WIDTH*2))) 3734*e977faadSmarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3735*e977faadSmarc 3736*e977faadSmarc 3737*e977faadSmarc /*-----------------------------------------------*/ 3738*e977faadSmarc 3739*e977faadSmarc adder->destination_x = FONT_X; 3740*e977faadSmarc adder->destination_y = FONT_Y - CHAR_HEIGHT; 3741*e977faadSmarc adder->fast_dest_dx = max_chars_line * CHAR_WIDTH * 2; 3742*e977faadSmarc adder->slow_dest_dy = CHAR_HEIGHT; 3743*e977faadSmarc 3744*e977faadSmarc /*--------------------------------------- 3745*e977faadSmarc * setup for processor to bitmap xfer */ 3746*e977faadSmarc 3747*e977faadSmarc write_ID(adder, CS_UPDATE_MASK, 0x0001); 3748*e977faadSmarc adder->cmd = PBT | OCRB | 2 | DTE | 2; 3749*e977faadSmarc 37507e911b15Skarels /*----------------------------------------------- 37517e911b15Skarels * iteratively do the processor to bitmap xfer */ 37527e911b15Skarels 37537e911b15Skarels for (i = 0; i < ROWS; ++i) { 37547e911b15Skarels 37557e911b15Skarels /* PTOB a scan line */ 37567e911b15Skarels 3757*e977faadSmarc for (j = 0, k = i; j < max_chars_line; ++j) { 37587e911b15Skarels 37597e911b15Skarels /* PTOB one scan of a char cell */ 37607e911b15Skarels 3761*e977faadSmarc packed = q_font[k + FONT_OFFSET]; 37627e911b15Skarels k += ROWS; 3763*e977faadSmarc packed |= ((short)q_font[k + FONT_OFFSET] << 8); 37647e911b15Skarels k += ROWS; 37657e911b15Skarels 37667e911b15Skarels wait_status(adder, TX_READY); 37677e911b15Skarels adder->id_data = packed; 37687e911b15Skarels } 37697e911b15Skarels } 37707e911b15Skarels 37717e911b15Skarels } /* ldfont */ 37727e911b15Skarels 37737e911b15Skarels /********************************************************************* 37747e911b15Skarels * 37757e911b15Skarels * led_control()... twiddle LK-201 LED's 37767e911b15Skarels * 37777e911b15Skarels ********************************************************************** 37787e911b15Skarels * 37797e911b15Skarels * led_control(unit, cmd, led_mask); 37807e911b15Skarels * u_int unit; QDSS number 37817e911b15Skarels * int cmd; LED enable/disable command 37827e911b15Skarels * int led_mask; which LED(s) to twiddle 37837e911b15Skarels * 37847e911b15Skarels *************/ 37857e911b15Skarels 37867e911b15Skarels led_control(unit, cmd, led_mask) 37877e911b15Skarels u_int unit; 37887e911b15Skarels int cmd; 37897e911b15Skarels int led_mask; 37907e911b15Skarels { 37917e911b15Skarels register int i; 37927e911b15Skarels register int status; 37937e911b15Skarels register struct duart *duart; 37947e911b15Skarels 37957e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 37967e911b15Skarels 37977e911b15Skarels for (i = 1000; i > 0; --i) { 37987e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 37997e911b15Skarels duart->dataA = cmd; 38007e911b15Skarels break; 38017e911b15Skarels } 38027e911b15Skarels } 38037e911b15Skarels 38047e911b15Skarels for (i = 1000; i > 0; --i) { 38057e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 38067e911b15Skarels duart->dataA = led_mask; 38077e911b15Skarels break; 38087e911b15Skarels } 38097e911b15Skarels } 38107e911b15Skarels 38117e911b15Skarels if (i == 0) 38127e911b15Skarels return(BAD); 38137e911b15Skarels 38147e911b15Skarels return(GOOD); 38157e911b15Skarels 38167e911b15Skarels } /* led_control */ 38177e911b15Skarels 38187e911b15Skarels /******************************************************************* 38197e911b15Skarels * 38207e911b15Skarels * scroll_up()... move the screen up one character height 38217e911b15Skarels * 38227e911b15Skarels ******************************************************************** 38237e911b15Skarels * 38247e911b15Skarels * calling convention: 38257e911b15Skarels * 38267e911b15Skarels * scroll_up(adder); 38277e911b15Skarels * struct adder *adder; ;address of adder 38287e911b15Skarels * 38297e911b15Skarels ********/ 38307e911b15Skarels 38317e911b15Skarels scroll_up(adder) 38327e911b15Skarels register struct adder *adder; 38337e911b15Skarels { 38347e911b15Skarels 38357e911b15Skarels /*------------------------------------------ 38367e911b15Skarels * setup VIPER operand control registers */ 38377e911b15Skarels 38387e911b15Skarels wait_status(adder, ADDRESS_COMPLETE); 38397e911b15Skarels 38407e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 38417e911b15Skarels 38427e911b15Skarels write_ID(adder, MASK_1, 0xFFFF); 38437e911b15Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 38447e911b15Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 38457e911b15Skarels 38467e911b15Skarels write_ID(adder, SRC1_OCR_B, 38477e911b15Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 38487e911b15Skarels write_ID(adder, DST_OCR_B, 38497e911b15Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 38507e911b15Skarels 38517e911b15Skarels /*---------------------------------------- 38527e911b15Skarels * load DESTINATION origin and vectors */ 38537e911b15Skarels 38547e911b15Skarels adder->fast_dest_dy = 0; 38557e911b15Skarels adder->slow_dest_dx = 0; 38567e911b15Skarels adder->error_1 = 0; 38577e911b15Skarels adder->error_2 = 0; 38587e911b15Skarels 38597e911b15Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 38607e911b15Skarels 38617e911b15Skarels adder->destination_x = 0; 38627e911b15Skarels adder->fast_dest_dx = 1024; 38637e911b15Skarels 38647e911b15Skarels adder->destination_y = 0; 38657e911b15Skarels adder->slow_dest_dy = 864 - CHAR_HEIGHT; 38667e911b15Skarels 38677e911b15Skarels /*----------------------------------- 38687e911b15Skarels * load SOURCE origin and vectors */ 38697e911b15Skarels 38707e911b15Skarels adder->source_1_x = 0; 38717e911b15Skarels adder->source_1_dx = 1024; 38727e911b15Skarels 38737e911b15Skarels adder->source_1_y = 0 + CHAR_HEIGHT; 38747e911b15Skarels adder->source_1_dy = 864 - CHAR_HEIGHT; 38757e911b15Skarels 38767e911b15Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 38777e911b15Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 38787e911b15Skarels 38797e911b15Skarels /*-------------------------------------------- 38807e911b15Skarels * do a rectangle clear of last screen line */ 38817e911b15Skarels 38827e911b15Skarels write_ID(adder, MASK_1, 0xffff); 38837e911b15Skarels write_ID(adder, SOURCE, 0xffff); 38847e911b15Skarels write_ID(adder,DST_OCR_B, 38857e911b15Skarels (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); 38867e911b15Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); 38877e911b15Skarels adder->error_1 = 0; 38887e911b15Skarels adder->error_2 = 0; 38897e911b15Skarels adder->slow_dest_dx = 0; /* set up the width of */ 38907e911b15Skarels adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ 38917e911b15Skarels 38927e911b15Skarels adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; 38937e911b15Skarels wait_status(adder, RASTEROP_COMPLETE); 38947e911b15Skarels adder->destination_x = 0; 38957e911b15Skarels adder->destination_y = 864 - CHAR_HEIGHT; 38967e911b15Skarels 38977e911b15Skarels adder->fast_dest_dx = 1024; /* set up the height */ 38987e911b15Skarels adder->fast_dest_dy = 0; /* of rectangle */ 38997e911b15Skarels 39007e911b15Skarels write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); 39017e911b15Skarels adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; 39027e911b15Skarels 39037e911b15Skarels } /* scroll_up */ 39047e911b15Skarels 39057e911b15Skarels /******************************************************************** 39067e911b15Skarels * 39077e911b15Skarels * init_shared()... init shared memory pointers and structures 39087e911b15Skarels * 39097e911b15Skarels ********************************************************************* 39107e911b15Skarels * 39117e911b15Skarels * calling convention: 39127e911b15Skarels * 39137e911b15Skarels * init_shared(unit); 39147e911b15Skarels * u_int unit; 39157e911b15Skarels * 39167e911b15Skarels ****************/ 39177e911b15Skarels 39187e911b15Skarels init_shared(unit) 39197e911b15Skarels register u_int unit; 39207e911b15Skarels { 39217e911b15Skarels register struct dga *dga; 39227e911b15Skarels 39237e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 39247e911b15Skarels 39257e911b15Skarels /*-------------------------------------------------- 39267e911b15Skarels * initialize the event queue pointers and header */ 39277e911b15Skarels 39287e911b15Skarels eq_header[unit] = (struct qdinput *) 39297e911b15Skarels ((((int)event_shared & ~(0x01FF)) + 512) 39307e911b15Skarels + (EVENT_BUFSIZE * unit)); 39317e911b15Skarels 39327e911b15Skarels eq_header[unit]->curs_pos.x = 0; 39337e911b15Skarels eq_header[unit]->curs_pos.y = 0; 39347e911b15Skarels 39357e911b15Skarels dga->x_cursor = TRANX(eq_header[unit]->curs_pos.x); 39367e911b15Skarels dga->y_cursor = TRANY(eq_header[unit]->curs_pos.y); 39377e911b15Skarels 39387e911b15Skarels eq_header[unit]->curs_box.left = 0; 39397e911b15Skarels eq_header[unit]->curs_box.right = 0; 39407e911b15Skarels eq_header[unit]->curs_box.top = 0; 39417e911b15Skarels eq_header[unit]->curs_box.bottom = 0; 39427e911b15Skarels 39437e911b15Skarels /*--------------------------------------------------------- 39447e911b15Skarels * assign a pointer to the DMA I/O buffer for this QDSS. */ 39457e911b15Skarels 39467e911b15Skarels DMAheader[unit] = (struct DMAreq_header *) 39477e911b15Skarels (((int)(&DMA_shared[0] + 512) & ~0x1FF) 39487e911b15Skarels + (DMAbuf_size * unit)); 39497e911b15Skarels 39507e911b15Skarels DMAheader[unit]->DMAreq = (struct DMAreq *) ((int)DMAheader[unit] 39517e911b15Skarels + sizeof(struct DMAreq_header)); 39527e911b15Skarels 39537e911b15Skarels DMAheader[unit]->QBAreg = 0; 39547e911b15Skarels DMAheader[unit]->status = 0; 39557e911b15Skarels DMAheader[unit]->shared_size = DMAbuf_size; 39567e911b15Skarels DMAheader[unit]->used = 0; 39577e911b15Skarels DMAheader[unit]->size = 10; /* default = 10 requests */ 39587e911b15Skarels DMAheader[unit]->oldest = 0; 39597e911b15Skarels DMAheader[unit]->newest = 0; 39607e911b15Skarels 39617e911b15Skarels /*----------------------------------------------------------- 39627e911b15Skarels * assign a pointer to the scroll structure for this QDSS. */ 39637e911b15Skarels 39647e911b15Skarels scroll[unit] = (struct scroll *) 39657e911b15Skarels (((int)(&scroll_shared[0] + 512) & ~0x1FF) 39667e911b15Skarels + (sizeof(struct scroll) * unit)); 39677e911b15Skarels 39687e911b15Skarels scroll[unit]->status = 0; 39697e911b15Skarels scroll[unit]->viper_constant = 0; 39707e911b15Skarels scroll[unit]->y_scroll_constant = 0; 39717e911b15Skarels scroll[unit]->y_offset = 0; 39727e911b15Skarels scroll[unit]->x_index_pending = 0; 39737e911b15Skarels scroll[unit]->y_index_pending = 0; 39747e911b15Skarels 39757e911b15Skarels /*---------------------------------------------------------------- 39767e911b15Skarels * assign a pointer to the color map write buffer for this QDSS */ 39777e911b15Skarels 39787e911b15Skarels color_buf[unit] = (struct color_buf *) 39797e911b15Skarels (((int)(&color_shared[0] + 512) & ~0x1FF) 39807e911b15Skarels + (COLOR_BUFSIZ * unit)); 39817e911b15Skarels 39827e911b15Skarels color_buf[unit]->status = 0; 39837e911b15Skarels color_buf[unit]->count = 0; 39847e911b15Skarels 39857e911b15Skarels } /* init_shared */ 39867e911b15Skarels 39877e911b15Skarels /********************************************************************* 39887e911b15Skarels * 39897e911b15Skarels * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map 39907e911b15Skarels * 39917e911b15Skarels ********************************************************************** 39927e911b15Skarels * 39937e911b15Skarels * calling convention: 39947e911b15Skarels * 39957e911b15Skarels * setup_dragon(); 39967e911b15Skarels * 39977e911b15Skarels * return: NONE 39987e911b15Skarels * 39997e911b15Skarels ************************/ 40007e911b15Skarels 40017e911b15Skarels setup_dragon(unit) 40027e911b15Skarels u_int unit; 40037e911b15Skarels { 40047e911b15Skarels 40057e911b15Skarels register struct adder *adder; 40067e911b15Skarels register struct dga *dga; 40077e911b15Skarels short *memcsr; 40087e911b15Skarels 40097e911b15Skarels int i; /* general purpose variables */ 40107e911b15Skarels int status; 40117e911b15Skarels 40127e911b15Skarels short top; /* clipping/scrolling boundaries */ 40137e911b15Skarels short bottom; 40147e911b15Skarels short right; 40157e911b15Skarels short left; 40167e911b15Skarels 40177e911b15Skarels short *red; /* color map pointers */ 40187e911b15Skarels short *green; 40197e911b15Skarels short *blue; 40207e911b15Skarels 40217e911b15Skarels /*------------------ 40227e911b15Skarels * init for setup */ 40237e911b15Skarels 40247e911b15Skarels adder = (struct adder *) qdmap[unit].adder; 40257e911b15Skarels dga = (struct dga *) qdmap[unit].dga; 40267e911b15Skarels memcsr = (short *) qdmap[unit].memcsr; 40277e911b15Skarels 40287e911b15Skarels dga->csr &= ~(DMA_IE | 0x700); /* halt DMA and kill the intrpts */ 40297e911b15Skarels *memcsr = SYNC_ON; /* blank screen and turn off LED's */ 40307e911b15Skarels adder->command = CANCEL; 40317e911b15Skarels 40327e911b15Skarels /*---------------------- 40337e911b15Skarels * set monitor timing */ 40347e911b15Skarels 40357e911b15Skarels adder->x_scan_count_0 = 0x2800; 40367e911b15Skarels adder->x_scan_count_1 = 0x1020; 40377e911b15Skarels adder->x_scan_count_2 = 0x003A; 40387e911b15Skarels adder->x_scan_count_3 = 0x38F0; 40397e911b15Skarels adder->x_scan_count_4 = 0x6128; 40407e911b15Skarels adder->x_scan_count_5 = 0x093A; 40417e911b15Skarels adder->x_scan_count_6 = 0x313C; 40427e911b15Skarels adder->sync_phase_adj = 0x0100; 40437e911b15Skarels adder->x_scan_conf = 0x00C8; 40447e911b15Skarels 40457e911b15Skarels /*--------------------------------------------------------- 40467e911b15Skarels * got a bug in secound pass ADDER! lets take care of it */ 40477e911b15Skarels 40487e911b15Skarels /* normally, just use the code in the following bug fix code, but to 40497e911b15Skarels * make repeated demos look pretty, load the registers as if there was 40507e911b15Skarels * no bug and then test to see if we are getting sync */ 40517e911b15Skarels 40527e911b15Skarels adder->y_scan_count_0 = 0x135F; 40537e911b15Skarels adder->y_scan_count_1 = 0x3363; 40547e911b15Skarels adder->y_scan_count_2 = 0x2366; 40557e911b15Skarels adder->y_scan_count_3 = 0x0388; 40567e911b15Skarels 40577e911b15Skarels /* if no sync, do the bug fix code */ 40587e911b15Skarels 40597e911b15Skarels if (wait_status(adder, VSYNC) == BAD) { 40607e911b15Skarels 40617e911b15Skarels /* first load all Y scan registers with very short frame and 40627e911b15Skarels * wait for scroll service. This guarantees at least one SYNC 40637e911b15Skarels * to fix the pass 2 Adder initialization bug (synchronizes 40647e911b15Skarels * XCINCH with DMSEEDH) */ 40657e911b15Skarels 40667e911b15Skarels adder->y_scan_count_0 = 0x01; 40677e911b15Skarels adder->y_scan_count_1 = 0x01; 40687e911b15Skarels adder->y_scan_count_2 = 0x01; 40697e911b15Skarels adder->y_scan_count_3 = 0x01; 40707e911b15Skarels 40717e911b15Skarels wait_status(adder, VSYNC); /* delay at least 1 full frame time */ 40727e911b15Skarels wait_status(adder, VSYNC); 40737e911b15Skarels 40747e911b15Skarels /* now load the REAL sync values (in reverse order just to 40757e911b15Skarels * be safe. */ 40767e911b15Skarels 40777e911b15Skarels adder->y_scan_count_3 = 0x0388; 40787e911b15Skarels adder->y_scan_count_2 = 0x2366; 40797e911b15Skarels adder->y_scan_count_1 = 0x3363; 40807e911b15Skarels adder->y_scan_count_0 = 0x135F; 40817e911b15Skarels } 40827e911b15Skarels 40837e911b15Skarels *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ 40847e911b15Skarels 40857e911b15Skarels /*---------------------------- 40867e911b15Skarels * zero the index registers */ 40877e911b15Skarels 40887e911b15Skarels adder->x_index_pending = 0; 40897e911b15Skarels adder->y_index_pending = 0; 40907e911b15Skarels adder->x_index_new = 0; 40917e911b15Skarels adder->y_index_new = 0; 40927e911b15Skarels adder->x_index_old = 0; 40937e911b15Skarels adder->y_index_old = 0; 40947e911b15Skarels 40957e911b15Skarels adder->pause = 0; 40967e911b15Skarels 40977e911b15Skarels /*---------------------------------------- 40987e911b15Skarels * set rasterop mode to normal pen down */ 40997e911b15Skarels 41007e911b15Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 41017e911b15Skarels 41027e911b15Skarels /*-------------------------------------------------- 41037e911b15Skarels * set the rasterop registers to a default values */ 41047e911b15Skarels 41057e911b15Skarels adder->source_1_dx = 1; 41067e911b15Skarels adder->source_1_dy = 1; 41077e911b15Skarels adder->source_1_x = 0; 41087e911b15Skarels adder->source_1_y = 0; 41097e911b15Skarels adder->destination_x = 0; 41107e911b15Skarels adder->destination_y = 0; 41117e911b15Skarels adder->fast_dest_dx = 1; 41127e911b15Skarels adder->fast_dest_dy = 0; 41137e911b15Skarels adder->slow_dest_dx = 0; 41147e911b15Skarels adder->slow_dest_dy = 1; 41157e911b15Skarels adder->error_1 = 0; 41167e911b15Skarels adder->error_2 = 0; 41177e911b15Skarels 41187e911b15Skarels /*------------------------ 41197e911b15Skarels * scale factor = unity */ 41207e911b15Skarels 41217e911b15Skarels adder->fast_scale = UNITY; 41227e911b15Skarels adder->slow_scale = UNITY; 41237e911b15Skarels 41247e911b15Skarels /*------------------------------- 41257e911b15Skarels * set the source 2 parameters */ 41267e911b15Skarels 41277e911b15Skarels adder->source_2_x = 0; 41287e911b15Skarels adder->source_2_y = 0; 41297e911b15Skarels adder->source_2_size = 0x0022; 41307e911b15Skarels 41317e911b15Skarels /*----------------------------------------------- 41327e911b15Skarels * initialize plane addresses for eight vipers */ 41337e911b15Skarels 41347e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 41357e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0000); 41367e911b15Skarels 41377e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0002); 41387e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0001); 41397e911b15Skarels 41407e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0004); 41417e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0002); 41427e911b15Skarels 41437e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0008); 41447e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0003); 41457e911b15Skarels 41467e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0010); 41477e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0004); 41487e911b15Skarels 41497e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0020); 41507e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0005); 41517e911b15Skarels 41527e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0040); 41537e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0006); 41547e911b15Skarels 41557e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x0080); 41567e911b15Skarels write_ID(adder, PLANE_ADDRESS, 0x0007); 41577e911b15Skarels 41587e911b15Skarels /* initialize the external registers. */ 41597e911b15Skarels 41607e911b15Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); 41617e911b15Skarels write_ID(adder, CS_SCROLL_MASK, 0x00FF); 41627e911b15Skarels 41637e911b15Skarels /* initialize resolution mode */ 41647e911b15Skarels 41657e911b15Skarels write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ 41667e911b15Skarels write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ 41677e911b15Skarels 41687e911b15Skarels /* initialize viper registers */ 41697e911b15Skarels 41707e911b15Skarels write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); 41717e911b15Skarels write_ID(adder, SCROLL_FILL, 0x0000); 41727e911b15Skarels 41737e911b15Skarels /*---------------------------------------------------- 41747e911b15Skarels * set clipping and scrolling limits to full screen */ 41757e911b15Skarels 41767e911b15Skarels for ( i = 1000, adder->status = 0 41777e911b15Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 41787e911b15Skarels ; --i); 41797e911b15Skarels 41807e911b15Skarels if (i == 0) 4181*e977faadSmarc printf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 41827e911b15Skarels 41837e911b15Skarels top = 0; 41847e911b15Skarels bottom = 2048; 41857e911b15Skarels left = 0; 41867e911b15Skarels right = 1024; 41877e911b15Skarels 41887e911b15Skarels adder->x_clip_min = left; 41897e911b15Skarels adder->x_clip_max = right; 41907e911b15Skarels adder->y_clip_min = top; 41917e911b15Skarels adder->y_clip_max = bottom; 41927e911b15Skarels 41937e911b15Skarels adder->scroll_x_min = left; 41947e911b15Skarels adder->scroll_x_max = right; 41957e911b15Skarels adder->scroll_y_min = top; 41967e911b15Skarels adder->scroll_y_max = bottom; 41977e911b15Skarels 41987e911b15Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 41997e911b15Skarels wait_status(adder, VSYNC); 42007e911b15Skarels 42017e911b15Skarels adder->x_index_pending = left; 42027e911b15Skarels adder->y_index_pending = top; 42037e911b15Skarels adder->x_index_new = left; 42047e911b15Skarels adder->y_index_new = top; 42057e911b15Skarels adder->x_index_old = left; 42067e911b15Skarels adder->y_index_old = top; 42077e911b15Skarels 42087e911b15Skarels for ( i = 1000, adder->status = 0 42097e911b15Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 42107e911b15Skarels ; --i); 42117e911b15Skarels 42127e911b15Skarels if (i == 0) 4213*e977faadSmarc printf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 42147e911b15Skarels 42157e911b15Skarels write_ID(adder, LEFT_SCROLL_MASK, 0x0000); 42167e911b15Skarels write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); 42177e911b15Skarels 42187e911b15Skarels /*------------------------------------------------------------ 42197e911b15Skarels * set source and the mask register to all ones (ie: white) */ 42207e911b15Skarels 42217e911b15Skarels write_ID(adder, SOURCE, 0xFFFF); 42227e911b15Skarels write_ID(adder, MASK_1, 0xFFFF); 42237e911b15Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 42247e911b15Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 42257e911b15Skarels 42267e911b15Skarels /*-------------------------------------------------------------- 42277e911b15Skarels * initialize Operand Control Register banks for fill command */ 42287e911b15Skarels 42297e911b15Skarels write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); 42307e911b15Skarels write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); 42317e911b15Skarels write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 42327e911b15Skarels 42337e911b15Skarels write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); 42347e911b15Skarels write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); 42357e911b15Skarels write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 42367e911b15Skarels 42377e911b15Skarels /*------------------------------------------------------------------ 42387e911b15Skarels * init Logic Unit Function registers, (these are just common values, 42397e911b15Skarels * and may be changed as required). */ 42407e911b15Skarels 42417e911b15Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 42427e911b15Skarels write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); 42437e911b15Skarels write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); 42447e911b15Skarels write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); 42457e911b15Skarels 42467e911b15Skarels /*---------------------------------------- 42477e911b15Skarels * load the color map for black & white */ 42487e911b15Skarels 42497e911b15Skarels for ( i = 0, adder->status = 0 42507e911b15Skarels ; i < 10000 && !((status = adder->status) & VSYNC) 42517e911b15Skarels ; ++i); 42527e911b15Skarels 42537e911b15Skarels if (i == 0) 4254*e977faadSmarc printf("\nqd%d: setup_dragon: timeout on VSYNC", unit); 42557e911b15Skarels 42567e911b15Skarels red = (short *) qdmap[unit].red; 42577e911b15Skarels green = (short *) qdmap[unit].green; 42587e911b15Skarels blue = (short *) qdmap[unit].blue; 42597e911b15Skarels 42607e911b15Skarels *red++ = 0x00; /* black */ 42617e911b15Skarels *green++ = 0x00; 42627e911b15Skarels *blue++ = 0x00; 42637e911b15Skarels 42647e911b15Skarels *red-- = 0xFF; /* white */ 42657e911b15Skarels *green-- = 0xFF; 42667e911b15Skarels *blue-- = 0xFF; 42677e911b15Skarels 42687e911b15Skarels /*---------------------------------- 42697e911b15Skarels * set color map for mouse cursor */ 42707e911b15Skarels 42717e911b15Skarels red += 254; 42727e911b15Skarels green += 254; 42737e911b15Skarels blue += 254; 42747e911b15Skarels 42757e911b15Skarels *red++ = 0x00; /* black */ 42767e911b15Skarels *green++ = 0x00; 42777e911b15Skarels *blue++ = 0x00; 42787e911b15Skarels 42797e911b15Skarels *red = 0xFF; /* white */ 42807e911b15Skarels *green = 0xFF; 42817e911b15Skarels *blue = 0xFF; 42827e911b15Skarels 42837e911b15Skarels return(0); 42847e911b15Skarels 42857e911b15Skarels } /* setup_dragon */ 42867e911b15Skarels 42877e911b15Skarels /****************************************************************** 42887e911b15Skarels * 42897e911b15Skarels * setup_input()... init the DUART and set defaults in input 42907e911b15Skarels * devices 42917e911b15Skarels * 42927e911b15Skarels ******************************************************************* 42937e911b15Skarels * 42947e911b15Skarels * calling convention: 42957e911b15Skarels * 42967e911b15Skarels * setup_input(unit); 42977e911b15Skarels * 42987e911b15Skarels * where: unit - is the QDSS unit number to be setup 42997e911b15Skarels * 43007e911b15Skarels *********/ 43017e911b15Skarels 43027e911b15Skarels setup_input(unit) 43037e911b15Skarels u_int unit; 43047e911b15Skarels { 43057e911b15Skarels register struct duart *duart; /* DUART register structure pointer */ 43067e911b15Skarels register int i; /* scratch variable */ 43077e911b15Skarels register int bits; 43087e911b15Skarels 43097e911b15Skarels char id_byte; 43107e911b15Skarels short status; 43117e911b15Skarels 43127e911b15Skarels /*--------------- 43137e911b15Skarels * init stuff */ 43147e911b15Skarels 43157e911b15Skarels duart = (struct duart *) qdmap[unit].duart; 43167e911b15Skarels duart->imask = 0; 43177e911b15Skarels 43187e911b15Skarels /*--------------------------------------------- 43197e911b15Skarels * setup the DUART for kbd & pointing device */ 43207e911b15Skarels 43217e911b15Skarels duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ 43227e911b15Skarels duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ 43237e911b15Skarels /* no RTS control,char error mode */ 43247e911b15Skarels duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ 43257e911b15Skarels /* no RTS control,no echo or loop */ 43267e911b15Skarels duart->cmdB = RESET_M; /* reset mode reg pntr for host */ 43277e911b15Skarels duart->modeB = 0x07; /* 8 bits, odd parity, rcv IE.. */ 43287e911b15Skarels /* ..no RTS cntrl, char error mode */ 43297e911b15Skarels duart->modeB = 0x07; /* 1 stop bit,CTS does not IE XMT */ 43307e911b15Skarels /* no RTS control,no echo or loop */ 43317e911b15Skarels 43327e911b15Skarels duart->auxctl = 0x00; /* baud rate set 1 */ 43337e911b15Skarels 43347e911b15Skarels duart->clkselA = 0x99; /* 4800 baud for kbd */ 43357e911b15Skarels duart->clkselB = 0x99; /* 4800 baud for mouse */ 43367e911b15Skarels 43377e911b15Skarels /* reset everything for keyboard */ 43387e911b15Skarels 43397e911b15Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 43407e911b15Skarels duart->cmdA = bits; 43417e911b15Skarels 43427e911b15Skarels /* reset everything for host */ 43437e911b15Skarels 43447e911b15Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 43457e911b15Skarels duart->cmdB = bits; 43467e911b15Skarels 43477e911b15Skarels duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ 43487e911b15Skarels duart->cmdB = EN_RCV | EN_XMT; /* enbl xmt & rcv for pointer device */ 43497e911b15Skarels 43507e911b15Skarels /*-------------------------------------------- 43517e911b15Skarels * init keyboard defaults (DUART channel A) */ 43527e911b15Skarels 43537e911b15Skarels for (i = 500; i > 0; --i) { 43547e911b15Skarels if ((status = duart->statusA) & XMT_RDY) { 43557e911b15Skarels duart->dataA = LK_DEFAULTS; 43567e911b15Skarels break; 43577e911b15Skarels } 43587e911b15Skarels } 43597e911b15Skarels 43607e911b15Skarels for (i = 100000; i > 0; --i) { 43617e911b15Skarels if ((status = duart->statusA) & RCV_RDY) { 43627e911b15Skarels break; 43637e911b15Skarels } 43647e911b15Skarels } 43657e911b15Skarels 43667e911b15Skarels status = duart->dataA; /* flush the ACK */ 43677e911b15Skarels 43687e911b15Skarels /*-------------------------------- 43697e911b15Skarels * identify the pointing device */ 43707e911b15Skarels 43717e911b15Skarels for (i = 500; i > 0; --i) { 43727e911b15Skarels if ((status = duart->statusB) & XMT_RDY) { 43737e911b15Skarels duart->dataB = SELF_TEST; 43747e911b15Skarels break; 43757e911b15Skarels } 43767e911b15Skarels } 43777e911b15Skarels 43787e911b15Skarels /*----------------------------------------- 43797e911b15Skarels * wait for 1st byte of self test report */ 43807e911b15Skarels 43817e911b15Skarels for (i = 100000; i > 0; --i) { 43827e911b15Skarels if ((status = duart->statusB) & RCV_RDY) { 43837e911b15Skarels break; 43847e911b15Skarels } 43857e911b15Skarels } 43867e911b15Skarels 43877e911b15Skarels if (i == 0) { 4388*e977faadSmarc printf("\nqd[%d]: setup_input: timeout on 1st byte of self test",unit); 43897e911b15Skarels goto OUT; 43907e911b15Skarels } 43917e911b15Skarels 43927e911b15Skarels status = duart->dataB; 43937e911b15Skarels 43947e911b15Skarels /*----------------------------------------- 43957e911b15Skarels * wait for ID byte of self test report */ 43967e911b15Skarels 43977e911b15Skarels for (i = 100000; i > 0; --i) { 43987e911b15Skarels if ((status = duart->statusB) & RCV_RDY) { 43997e911b15Skarels break; 44007e911b15Skarels } 44017e911b15Skarels } 44027e911b15Skarels 44037e911b15Skarels if (i == 0) { 4404*e977faadSmarc printf("\nqd[%d]: setup_input: timeout on 2nd byte of self test", unit); 44057e911b15Skarels goto OUT; 44067e911b15Skarels } 44077e911b15Skarels 44087e911b15Skarels id_byte = duart->dataB; 44097e911b15Skarels 44107e911b15Skarels /*------------------------------------ 44117e911b15Skarels * wait for other bytes to come in */ 44127e911b15Skarels 44137e911b15Skarels for (i = 100000; i > 0; --i) { 44147e911b15Skarels if ((status = duart->statusB) & RCV_RDY) { 44157e911b15Skarels status = duart->dataB; 44167e911b15Skarels break; 44177e911b15Skarels } 44187e911b15Skarels } 44197e911b15Skarels 44207e911b15Skarels if (i == 0) { 4421*e977faadSmarc printf("\nqd[%d]: setup_input: timeout on 3rd byte of self test", unit); 44227e911b15Skarels goto OUT; 44237e911b15Skarels } 44247e911b15Skarels 44257e911b15Skarels for (i = 100000; i > 0; --i) { 44267e911b15Skarels if ((status = duart->statusB) & RCV_RDY) { 44277e911b15Skarels status = duart->dataB; 44287e911b15Skarels break; 44297e911b15Skarels } 44307e911b15Skarels } 44317e911b15Skarels 44327e911b15Skarels if (i == 0) { 4433*e977faadSmarc printf("\nqd[%d]: setup_input: timeout on 4th byte of self test\n", unit); 44347e911b15Skarels goto OUT; 44357e911b15Skarels } 44367e911b15Skarels 44377e911b15Skarels /*---------------------------------------------- 44387e911b15Skarels * flag pointing device type and set defaults */ 44397e911b15Skarels 44407e911b15Skarels for (i=100000; i>0; --i); 44417e911b15Skarels 44427e911b15Skarels if ((id_byte & 0x0F) != TABLET_ID) { 44437e911b15Skarels 44447e911b15Skarels qdflags[unit].pntr_id = MOUSE_ID; 44457e911b15Skarels 44467e911b15Skarels for (i = 500; i > 0; --i) { 44477e911b15Skarels if ((status = duart->statusB) & XMT_RDY) { 44487e911b15Skarels duart->dataB = INC_STREAM_MODE; 44497e911b15Skarels break; 44507e911b15Skarels } 44517e911b15Skarels } 44527e911b15Skarels } else { 44537e911b15Skarels 44547e911b15Skarels qdflags[unit].pntr_id = TABLET_ID; 44557e911b15Skarels 44567e911b15Skarels for (i = 500; i > 0; --i) { 44577e911b15Skarels if ((status = duart->statusB) & XMT_RDY) { 44587e911b15Skarels duart->dataB = T_STREAM; 44597e911b15Skarels break; 44607e911b15Skarels } 44617e911b15Skarels } 44627e911b15Skarels } 44637e911b15Skarels 44647e911b15Skarels /*-------- 44657e911b15Skarels * exit */ 44667e911b15Skarels 44677e911b15Skarels OUT: 44687e911b15Skarels duart->imask = qdflags[unit].duart_imask; 44697e911b15Skarels return(0); 44707e911b15Skarels 44717e911b15Skarels } /* setup_input */ 44727e911b15Skarels 44737e911b15Skarels /********************************************************************** 44747e911b15Skarels * 44757e911b15Skarels * wait_status()... delay for at least one display frame time 44767e911b15Skarels * 44777e911b15Skarels *********************************************************************** 44787e911b15Skarels * 44797e911b15Skarels * calling convention: 44807e911b15Skarels * 44817e911b15Skarels * wait_status(adder, mask); 44827e911b15Skarels * struct *adder adder; 44837e911b15Skarels * int mask; 44847e911b15Skarels * 44857e911b15Skarels * return: BAD means that we timed out without ever seeing the 44867e911b15Skarels * vertical sync status bit 44877e911b15Skarels * GOOD otherwise 44887e911b15Skarels * 44897e911b15Skarels **************/ 44907e911b15Skarels 44917e911b15Skarels wait_status(adder, mask) 44927e911b15Skarels register struct adder *adder; 44937e911b15Skarels register int mask; 44947e911b15Skarels { 44957e911b15Skarels register short status; 44967e911b15Skarels int i; 44977e911b15Skarels 44987e911b15Skarels for ( i = 10000, adder->status = 0 44997e911b15Skarels ; i > 0 && !((status = adder->status) & mask) 45007e911b15Skarels ; --i); 45017e911b15Skarels 45027e911b15Skarels if (i == 0) { 4503*e977faadSmarc printf("\nwait_status: timeout polling for 0x%x in adder->status", mask); 45047e911b15Skarels return(BAD); 45057e911b15Skarels } 45067e911b15Skarels 45077e911b15Skarels return(GOOD); 45087e911b15Skarels 45097e911b15Skarels } /* wait_status */ 45107e911b15Skarels 45117e911b15Skarels /********************************************************************** 45127e911b15Skarels * 45137e911b15Skarels * write_ID()... write out onto the ID bus 45147e911b15Skarels * 45157e911b15Skarels *********************************************************************** 45167e911b15Skarels * 45177e911b15Skarels * calling convention: 45187e911b15Skarels * 45197e911b15Skarels * struct *adder adder; ;pntr to ADDER structure 45207e911b15Skarels * short adrs; ;VIPER address 45217e911b15Skarels * short data; ;data to be written 45227e911b15Skarels * write_ID(adder); 45237e911b15Skarels * 45247e911b15Skarels * return: BAD means that we timed out waiting for status bits 45257e911b15Skarels * VIPER-access-specific status bits 45267e911b15Skarels * GOOD otherwise 45277e911b15Skarels * 45287e911b15Skarels **************/ 45297e911b15Skarels 45307e911b15Skarels write_ID(adder, adrs, data) 45317e911b15Skarels register struct adder *adder; 45327e911b15Skarels register short adrs; 45337e911b15Skarels register short data; 45347e911b15Skarels { 45357e911b15Skarels int i; 45367e911b15Skarels short status; 45377e911b15Skarels 4538*e977faadSmarc for ( i = 100000, adder->status = 0 4539*e977faadSmarc ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 4540*e977faadSmarc ; --i); 45417e911b15Skarels 45427e911b15Skarels if (i == 0) 45437e911b15Skarels goto ERR; 45447e911b15Skarels 4545*e977faadSmarc for ( i = 100000, adder->status = 0 4546*e977faadSmarc ; i > 0 && !((status = adder->status) & TX_READY) 4547*e977faadSmarc ; --i); 45487e911b15Skarels 45497e911b15Skarels if (i > 0) { 45507e911b15Skarels adder->id_data = data; 45517e911b15Skarels adder->command = ID_LOAD | adrs; 45527e911b15Skarels return(GOOD); 45537e911b15Skarels } 45547e911b15Skarels 45557e911b15Skarels ERR: 4556*e977faadSmarc printf("\nwrite_ID: timeout trying to write to VIPER"); 45577e911b15Skarels return(BAD); 45587e911b15Skarels 45597e911b15Skarels } /* write_ID */ 4560*e977faadSmarc 4561006e9885Smarc #endif 4562