134511Smarc /* 234511Smarc * Copyright (c) 1982, 1986 Regents of the University of California. 334511Smarc * All rights reserved. The Berkeley software License Agreement 434511Smarc * specifies the terms and conditions for redistribution. 534511Smarc * 6*34615Smarc * @(#)qd.c 1.6 Berkeley 06/01/88 734511Smarc * 8*34615Smarc * derived from: "@(#)qd.c ULTRIX"; 934511Smarc */ 1030391Skarels /************************************************************************ 1134511Smarc * * 12*34615Smarc * Copyright (c) 1985-1988 by * 1330391Skarels * Digital Equipment Corporation, Maynard, MA * 1430391Skarels * All rights reserved. * 1530391Skarels * * 1630391Skarels * This software is furnished under a license and may be used and * 1730391Skarels * copied only in accordance with the terms of such license and * 1830391Skarels * with the inclusion of the above copyright notice. This * 1930391Skarels * software or any other copies thereof may not be provided or * 2030391Skarels * otherwise made available to any other person. No title to and * 2130391Skarels * ownership of the software is hereby transferred. * 2230391Skarels * * 2330391Skarels * The information in this software is subject to change without * 2430391Skarels * notice and should not be construed as a commitment by Digital * 2530391Skarels * Equipment Corporation. * 2630391Skarels * * 2730391Skarels * Digital assumes no responsibility for the use or reliability * 2830391Skarels * of its software on equipment which is not supplied by Digital. * 2930391Skarels * * 3030391Skarels *************************************************************************/ 31*34615Smarc 3230391Skarels /* 33*34615Smarc * qd.c 34*34615Smarc * 35*34615Smarc * Modification history 36*34615Smarc * 37*34615Smarc * QDSS workstation driver 38*34615Smarc * 39*34615Smarc * 40*34615Smarc * 1-Dec-87 - Tim Burke 41*34615Smarc * 42*34615Smarc * Added support for both System V termio(7) and POSIX termios(7). These 43*34615Smarc * changes also include support for 8-bit canonical processing. Changes 44*34615Smarc * involve: 45*34615Smarc * 46*34615Smarc * - Default settings on first open depend on mode of open. For termio 47*34615Smarc * opens the defaults are "RAW" style, while non-termio opens default 48*34615Smarc * to the traditional "cooked" style. 49*34615Smarc * - The driver now represents its terminal attributes and special 50*34615Smarc * characters in the POSIX termios data structure. This contrasts the 51*34615Smarc * original approach of storing attributes and special chars in the 52*34615Smarc * t_flags, ltchars and tchars. 53*34615Smarc * - Addition of LPASS8 to local mode word for 8-bit canonical support. 54*34615Smarc * 55*34615Smarc * 28-Sep-87 - Ali Rafieymehr 56*34615Smarc * Fixed a bug in qddint() routine. The bug was discovered on CVAX. 57*34615Smarc * Incorrect logic was used when taking an entry from the request queue. 58*34615Smarc * 59*34615Smarc * 12-Oct-87 - Tim Burke 60*34615Smarc * Modified driver to provide 8-bit support to the console port. To do 61*34615Smarc * this characters are defined in the remainder of the first 15 rows of 62*34615Smarc * off screen memory as well as in next 15 rows. 63*34615Smarc * 64*34615Smarc * 2-Aug-87 - Fred Canter 65*34615Smarc * Use TANDEM mode on qconsole for flow control of writes to 66*34615Smarc * /dev/console. 67*34615Smarc * 68*34615Smarc * 12-Jun-87 - Tim Burke 69*34615Smarc * 70*34615Smarc * Added full TERMIO functionality to terminal subsystem. 71*34615Smarc * Changed open routine to setup propper default settings if the line 72*34615Smarc * is not being used as a graphics device. Added defines of defaults. 73*34615Smarc * 74*34615Smarc * 75*34615Smarc * 14-May-87 - Fred Canter 76*34615Smarc * Changed default state of kernel_loop to on. 77*34615Smarc * 78*34615Smarc * 21-Apr-87 - Brian Stevens 79*34615Smarc * Xos support 80*34615Smarc * 81*34615Smarc * 16-Apr-87 - Fred Canter (for Brian Stevens) 82*34615Smarc * Multi-head GPX changes. 83*34615Smarc * 84*34615Smarc * 19-Mar-87 - Fred Canter (for Brian Stevens) 85*34615Smarc * Added X in the kernel support. 86*34615Smarc * 87*34615Smarc * 16-Dec-86 - Brian Stevens 88*34615Smarc * 89*34615Smarc * added support so "select" could be called on tty type device 90*34615Smarc * fixed rlogin bug 91*34615Smarc * 92*34615Smarc * 30-Oct-86 - Brian Stevens 93*34615Smarc * 94*34615Smarc * Removed the mprintf for "unexpected interrupts" 95*34615Smarc * 96*34615Smarc * 26-Aug-86 - rsp (Ricky Palmer) 97*34615Smarc * 98*34615Smarc * Cleaned up devioctl code to (1) zero out devget structure 99*34615Smarc * upon entry and (2) use strlen instead of fixed storage 100*34615Smarc * for bcopy's. 101*34615Smarc * 102*34615Smarc * 21-Jul-86 - Ram Rao 103*34615Smarc * allowed cursor rectangle to hang (partially) off the 104*34615Smarc * top and left of screen 105*34615Smarc * 106*34615Smarc * 11-Jul-86 - ricky palmer 107*34615Smarc * 108*34615Smarc * Added adpt and nexus fields to DEVIOCGET code. 109*34615Smarc * 110*34615Smarc * 02-July-86 - Brian Stevens 111*34615Smarc * 112*34615Smarc * added support for console writing to second QDSS display 113*34615Smarc * 114*34615Smarc * 20-May-86 - ricky palmer 115*34615Smarc * 116*34615Smarc * Added new DEVIOCGET ioctl request code. V2.0 117*34615Smarc * 118*34615Smarc * 16-Apr-86 -- darrell 119*34615Smarc * badaddr is now called via the macro BADADDR 120*34615Smarc * 121*34615Smarc * 14-Apr-86 -- afd 122*34615Smarc * Changed UMEMmap to QVmap and umem to qvmem. 123*34615Smarc * 124*34615Smarc * v_console() is now refered to as v_consputc, and there is a 125*34615Smarc * corresponding v_consgetc() (defined in /sys/vax/conf.c). 126*34615Smarc * 127*34615Smarc * Added "qdgetc()" routine for console read. Needed to read 128*34615Smarc * user's answer to the "root device?" prompt with a generic kernel. 129*34615Smarc * 130*34615Smarc * 19-Mar-86 -- pmk 131*34615Smarc * Change DELAY to 20000, because microdelay now in real microsec. 132*34615Smarc * 133*34615Smarc * 18-mar-86 -- jaw br/cvec changed to NOT use registers. 134*34615Smarc * 135*34615Smarc * 11 mar 86 darrell replaced percpu with cpusw, and removed all but 136*34615Smarc * one global reference 137*34615Smarc * 19 feb 86 bstevens no report of motion event on puck/stylus button action 138*34615Smarc * 18 feb 86 bstevens put in cursor box support for tablets 139*34615Smarc * 18-Mar-86 -- jaw add routines to cpu switch for nexus/unibus addreses 140*34615Smarc * also got rid of some globals like nexnum. 141*34615Smarc * ka8800 cleanup. 142*34615Smarc * 06 dec 85 longo added LK-201 error reporting for graphics device ops 143*34615Smarc * 03 dec 85 longo made qddint() clear active bit on error 144*34615Smarc * 02 dec 85 longo fixed up some crocks in the error messages 145*34615Smarc * 25 nov 85 longo added error handling to DMA ISR and single user locking 146*34615Smarc * 19 nov 85 longo eliminated "set_defaults()" by breaking out sub-calls. 147*34615Smarc * Changed init_shared to do real init of scroll struct 148*34615Smarc * 12 nov 85 longo fixed bug in open that broke alternate console re-direct 149*34615Smarc * 11 nov 85 longo changed "_vs_eventqueue" references to "qdinput" 150*34615Smarc * 08 nov 85 longo improved select service for read/write select wakeup. 151*34615Smarc * Also set ISR's to ipl4 to allow the interval timer in. 152*34615Smarc * 04 nov 85 longo fixed bugs in mouse button reporting and dma request stuff 153*34615Smarc * 30 oct 85 longo DMA to/from user space is in place 154*34615Smarc * 14 oct 85 longo added kernel msg redirect and QD_RDCURSOR ioctl 155*34615Smarc * 03 oct 85 longo added support for multiple QDSS's 156*34615Smarc * 02 oct 85 longo added color map loading services in qdioctl() & qdaint() 157*34615Smarc * 30 sep 85 longo added DMA interrupt services 158*34615Smarc * 18 sep 85 longo added scroll services to "qdaint()" adder intrpt service 159*34615Smarc * and put in supporting ioctl's 160*34615Smarc * 04 sep 85 longo initial implementation of DMA is working 161*34615Smarc * 17 aug 85 longo added support for the QDSS to be system console 162*34615Smarc * 05 aug 85 longo now using qfont (QVSS & QDSS) as linked object 163*34615Smarc * 12 jun 85 longo added mouse event loading to "qdiint()" 164*34615Smarc * 31 may 85 longo put live interrupts into the probe() routine 165*34615Smarc * 30 may 85 longo event queue shared memory implementation is now alive 166*34615Smarc * 29 may 85 longo LK-201 input is now interrupt driven 167*34615Smarc * 25 apr 85 longo MAPDEVICE works 168*34615Smarc * 14 mar 85 longo created 169*34615Smarc * 170*34615Smarc * todo: fix rlogin bug in console stuff 171*34615Smarc * cat -u console redirection 172*34615Smarc * check error return from strategy routine 173*34615Smarc * verify TOY time stuff (what format?) 174*34615Smarc * look at system based macro implementation of VTOP 175*34615Smarc * 17630391Skarels */ 17730391Skarels 178*34615Smarc #include "qd.h" /* # of QDSS's the system is configured for */ 179*34615Smarc 18034511Smarc #if NQD > 0 181*34615Smarc #include "types.h" 182*34615Smarc #include "../machine/pte.h" /* page table values */ 183*34615Smarc #include "../machine/mtpr.h" /* VAX register access stuff */ 18434511Smarc #include "../machine/cpu.h" 185*34615Smarc #include "param.h" /* general system params & macros */ 186*34615Smarc #include "conf.h" /* "linesw" tty driver dispatch */ 187*34615Smarc #include "dir.h" /* for directory handling */ 188*34615Smarc #include "user.h" /* user structure (what else?) */ 189*34615Smarc #include "qdioctl.h" /* ioctl call values */ 19034511Smarc #include "tty.h" 191*34615Smarc #include "map.h" /* resource allocation map struct */ 192*34615Smarc #include "buf.h" /* buf structs */ 193*34615Smarc #include "vm.h" /* includes 'vm' header files */ 194*34615Smarc #include "bk.h" /* BKINPUT macro for line stuff */ 195*34615Smarc #include "clist.h" /* char list handling structs */ 196*34615Smarc #include "file.h" /* file I/O definitions */ 197*34615Smarc #include "uio.h" /* write/read call structs */ 198*34615Smarc #include "kernel.h" /* clock handling structs */ 199*34615Smarc #ifdef notdef /* notneeded */ 200*34615Smarc #include "cpuconf.h" 201*34615Smarc #include "devio.h" 202*34615Smarc #endif 203*34615Smarc #include "exec.h" 204*34615Smarc #include "proc.h" 205*34615Smarc 206*34615Smarc #include "ubareg.h" /* uba & 'qba' register structs */ 207*34615Smarc #include "ubavar.h" /* uba structs & uba map externs */ 20834511Smarc #include "syslog.h" 20930391Skarels 210*34615Smarc #include "qduser.h" /* definitions shared with my client */ 211*34615Smarc #include "qdreg.h" /* QDSS device register structures */ 212*34615Smarc /*----------------------------------------------------------- 213*34615Smarc * QDSS driver status flags for tracking operational state */ 21432012Smarc 215*34615Smarc struct qdflags { 21632012Smarc 217*34615Smarc u_int inuse; /* which minor dev's are in use now */ 218*34615Smarc u_int config; /* I/O page register content */ 219*34615Smarc u_int mapped; /* user mapping status word */ 220*34615Smarc u_int kernel_loop; /* if kernel console is redirected */ 221*34615Smarc u_int user_dma; /* DMA from user space in progress */ 222*34615Smarc u_short pntr_id; /* type code of pointing device */ 223*34615Smarc u_short duart_imask; /* shadowing for duart intrpt mask reg */ 224*34615Smarc u_short adder_ie; /* shadowing for adder intrpt enbl reg */ 225*34615Smarc u_short curs_acc; /* cursor acceleration factor */ 226*34615Smarc u_short curs_thr; /* cursor acceleration threshold level */ 227*34615Smarc u_short tab_res; /* tablet resolution factor */ 228*34615Smarc u_short selmask; /* mask for active qd select entries */ 229*34615Smarc }; 23032012Smarc 231*34615Smarc /* bit definitions for "inuse" entry */ 23234511Smarc 23332012Smarc #define CONS_DEV 0x01 23432012Smarc #define ALTCONS_DEV 0x02 23532012Smarc #define GRAPHIC_DEV 0x04 23632012Smarc 237*34615Smarc /* bit definitions for 'mapped' member of flag structure */ 238*34615Smarc 23932012Smarc #define MAPDEV 0x01 /* hardware is mapped */ 24032012Smarc #define MAPDMA 0x02 /* DMA buffer mapped */ 24132012Smarc #define MAPEQ 0x04 /* event queue buffer mapped */ 24232012Smarc #define MAPSCR 0x08 /* scroll param area mapped */ 24332012Smarc #define MAPCOLOR 0x10 /* color map writing buffer mapped */ 24432012Smarc 245*34615Smarc /* bit definitions for 'selmask' member of qdflag structure */ 24632012Smarc 24732012Smarc #define SEL_READ 0x01 /* read select is active */ 24832012Smarc #define SEL_WRITE 0x02 /* write select is active */ 24932012Smarc 250*34615Smarc /*---------------------------------------------- 251*34615Smarc * constants used in shared memory operations */ 25232012Smarc 25332012Smarc #define EVENT_BUFSIZE 1024 /* # of bytes per device's event buffer */ 254*34615Smarc 25532012Smarc #define MAXEVENTS ( (EVENT_BUFSIZE - sizeof(struct qdinput)) \ 25632012Smarc / sizeof(struct _vs_event) ) 257*34615Smarc 25834527Smarc #define DMA_BUFSIZ (1024 * 10) 259*34615Smarc 26032012Smarc #define COLOR_BUFSIZ ((sizeof(struct color_buf) + 512) & ~0x01FF) 26132012Smarc 262*34615Smarc /*******************************************************************/ 263*34615Smarc 264*34615Smarc extern char qvmem[][128*NBPG]; 265*34615Smarc extern struct pte QVmap[][128]; 266*34615Smarc 267*34615Smarc 268*34615Smarc /*-------------------------------------------------------------------------- 26932012Smarc * reference to an array of "uba_device" structures built by the auto 27032012Smarc * configuration program. The uba_device structure decribes the device 27132012Smarc * sufficiently for the driver to talk to it. The auto configuration code 27232012Smarc * fills in the uba_device structures (located in ioconf.c) from user 273*34615Smarc * maintained info. */ 27432012Smarc 275*34615Smarc struct uba_device *qdinfo[NQD]; /* array of pntrs to each QDSS's */ 276*34615Smarc /* uba structures */ 277*34615Smarc struct tty qd_tty[NQD*4]; /* teletype structures for each.. */ 278*34615Smarc /* ..possible minor device */ 27932012Smarc 280*34615Smarc struct qd_softc qd_softc[NQD]; 28132012Smarc 282*34615Smarc /*---------------------------------------------------------- 283*34615Smarc * static storage used by multiple functions in this code */ 28432012Smarc 285*34615Smarc int Qbus_unmap[NQD]; /* Qbus mapper release code */ 286*34615Smarc struct qdflags qdflags[NQD]; /* QDSS device status flags */ 287*34615Smarc struct qdmap qdmap[NQD]; /* QDSS register map structure */ 288*34615Smarc caddr_t qdbase[NQD]; /* base address of each QDSS unit */ 289*34615Smarc struct buf qdbuf[NQD]; /* buf structs used by strategy */ 290*34615Smarc char one_only[NQD]; /* lock for single process access */ 291*34615Smarc 292*34615Smarc /*------------------------------------------------------------------------ 293*34615Smarc * the array "event_shared[]" is made up of a number of event queue buffers 29432012Smarc * equal to the number of QDSS's configured into the running kernel (NQD). 29532012Smarc * Each event queue buffer begins with an event queue header (struct qdinput) 29632012Smarc * followed by a group of event queue entries (struct _vs_event). The array 29732012Smarc * "*eq_header[]" is an array of pointers to the start of each event queue 298*34615Smarc * buffer in "event_shared[]". */ 29932012Smarc 30032012Smarc #define EQSIZE ((EVENT_BUFSIZE * NQD) + 512) 30132012Smarc 302*34615Smarc char event_shared[EQSIZE]; /* reserve space for event bufs */ 303*34615Smarc struct qdinput *eq_header[NQD]; /* event queue header pntrs */ 30432012Smarc 305*34615Smarc /*-------------------------------------------------------------------------- 30632012Smarc * This allocation method reserves enough memory pages for NQD shared DMA I/O 30732012Smarc * buffers. Each buffer must consume an integral number of memory pages to 30832012Smarc * guarantee that a following buffer will begin on a page boundary. Also, 30932012Smarc * enough space is allocated so that the FIRST I/O buffer can start at the 31032012Smarc * 1st page boundary after "&DMA_shared". Page boundaries are used so that 311*34615Smarc * memory protections can be turned on/off for individual buffers. */ 31232012Smarc 31332012Smarc #define IOBUFSIZE ((DMA_BUFSIZ * NQD) + 512) 31432012Smarc 315*34615Smarc char DMA_shared[IOBUFSIZE]; /* reserve I/O buffer space */ 316*34615Smarc struct DMAreq_header *DMAheader[NQD]; /* DMA buffer header pntrs */ 31732012Smarc 318*34615Smarc /*------------------------------------------------------------------------- 31932012Smarc * The driver assists a client in scroll operations by loading dragon 32032012Smarc * registers from an interrupt service routine. The loading is done using 32132012Smarc * parameters found in memory shrade between the driver and it's client. 32232012Smarc * The scroll parameter structures are ALL loacted in the same memory page 323*34615Smarc * for reasons of memory economy. */ 32432012Smarc 325*34615Smarc char scroll_shared[2 * 512]; /* reserve space for scroll structs */ 326*34615Smarc struct scroll *scroll[NQD]; /* pointers to scroll structures */ 32732012Smarc 328*34615Smarc /*----------------------------------------------------------------------- 32932012Smarc * the driver is programmable to provide the user with color map write 33032012Smarc * services at VSYNC interrupt time. At interrupt time the driver loads 331*34615Smarc * the color map with any user-requested load data found in shared memory */ 33232012Smarc 33332012Smarc #define COLOR_SHARED ((COLOR_BUFSIZ * NQD) + 512) 33432012Smarc 335*34615Smarc char color_shared[COLOR_SHARED]; /* reserve space: color bufs */ 336*34615Smarc struct color_buf *color_buf[NQD]; /* pointers to color bufs */ 33732012Smarc 338*34615Smarc /*-------------------------------- 339*34615Smarc * mouse input event structures */ 34032012Smarc 341*34615Smarc struct mouse_report last_rep[NQD]; 342*34615Smarc struct mouse_report current_rep[NQD]; 34332012Smarc 344*34615Smarc /*---------------------------- 345*34615Smarc * input event "select" use */ 34632012Smarc 347*34615Smarc struct proc *rsel[NQD]; /* process waiting for select */ 34832012Smarc 349*34615Smarc /*---------------------------- 350*34615Smarc * console cursor structure */ 35132012Smarc 352*34615Smarc struct _vs_cursor cursor[NQD]; 35332012Smarc 354*34615Smarc /*---------------------------- 355*34615Smarc * count of successfully probed qd's */ 35632012Smarc 357*34615Smarc int qdcount = 0; 35832012Smarc 35932012Smarc 360*34615Smarc /************************************************************************/ 36132012Smarc 362*34615Smarc int nNQD = NQD; 36332012Smarc 364*34615Smarc int DMAbuf_size = DMA_BUFSIZ; 36532012Smarc 366*34615Smarc 367*34615Smarc #define QDSSMAJOR 41 /* QDSS major device number */ 368*34615Smarc #ifdef notdef /* on ultrix */ 369*34615Smarc extern int ws_display_type; 370*34615Smarc extern int ws_display_units; 371*34615Smarc #endif 372*34615Smarc /* don't need these */ 373*34615Smarc int ws_display_type; 374*34615Smarc int ws_display_units; 375*34615Smarc 376*34615Smarc int QDlast_DMAtype; /* type of the last DMA operation */ 377*34615Smarc 378*34615Smarc /*--------------------------------------------------------------------- 379*34615Smarc * macro to get system time. Used to time stamp event queue entries */ 380*34615Smarc 38130391Skarels #define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000)) 38230391Skarels 383*34615Smarc /*-------------------------------------------------------------------------- 38430391Skarels * the "ioconf.c" program, built and used by auto config, externally refers 385*34615Smarc * to definitions below. */ 38630391Skarels 387*34615Smarc int qdprobe(); 388*34615Smarc int qdattach(); 389*34615Smarc int qddint(); /* DMA gate array intrpt service */ 390*34615Smarc int qdaint(); /* Dragon ADDER intrpt service */ 391*34615Smarc int qdiint(); 39230391Skarels 393*34615Smarc u_short qdstd[] = { 0 }; 39430391Skarels 395*34615Smarc struct uba_driver qddriver = { /* externally referenced: ioconf.c */ 39630391Skarels 397*34615Smarc qdprobe, /* device probe entry */ 398*34615Smarc 0, /* no slave device */ 399*34615Smarc qdattach, /* device attach entry */ 400*34615Smarc 0, /* no "fill csr/ba to start" */ 401*34615Smarc qdstd, /* device addresses */ 402*34615Smarc "qd", /* device name string */ 403*34615Smarc qdinfo /* ptr to QDSS's uba_device struct */ 404*34615Smarc }; 40530391Skarels 406*34615Smarc /*------------------- 40730391Skarels * general defines */ 40830391Skarels 409*34615Smarc #define QDPRIOR (PZERO-1) /* must be negative */ 41030391Skarels 41130391Skarels #define FALSE 0 41230391Skarels #define TRUE ~FALSE 41330391Skarels 41430391Skarels #define BAD -1 41530391Skarels #define GOOD 0 41630391Skarels 417*34615Smarc /*----------------------------------------------------------------------- 418*34615Smarc * macro to create a system virtual page number from system virtual adrs */ 41930391Skarels 420*34615Smarc #define VTOP(x) (((int)x & ~0xC0000000) >> PGSHIFT) /* convert qvmem adrs */ 421*34615Smarc /* to system page # */ 42230391Skarels 423*34615Smarc /*------------------------------------------------------------------ 424*34615Smarc * QDSS register address offsets from start of QDSS address space */ 42530391Skarels 42630391Skarels #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ 42730391Skarels 42830391Skarels #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ 42930391Skarels #define TMPSTART 0x8000 /* offset of template RAM from base adrs */ 43030391Skarels 43130391Skarels #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ 43230391Skarels #define REGSTART 0xC000 /* offset of reg pages from base adrs */ 43330391Skarels 43430391Skarels #define ADDER (REGSTART+0x000) 43530391Skarels #define DGA (REGSTART+0x200) 43630391Skarels #define DUART (REGSTART+0x400) 43730391Skarels #define MEMCSR (REGSTART+0x800) 43830391Skarels 43930391Skarels #define CLRSIZE (3 * 512) /* color map size */ 44030391Skarels #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ 44130391Skarels /* 0x0C00 really */ 44230391Skarels #define RED (CLRSTART+0x000) 44330391Skarels #define BLUE (CLRSTART+0x200) 44430391Skarels #define GREEN (CLRSTART+0x400) 44530391Skarels 446*34615Smarc /*--------------------------------------------------------------- 447*34615Smarc * values used in mapping QDSS hardware into the Q memory space */ 44830391Skarels 44930391Skarels #define CHUNK (64 * 1024) 450*34615Smarc #define QMEMSIZE (1024 * 1024 * 4) /* 4 meg */ 45130391Skarels 452*34615Smarc /*---------------------------------------------------------------------- 45330391Skarels * QDSS minor device numbers. The *real* minor device numbers are in 45430391Skarels * the bottom two bits of the major/minor device spec. Bits 2 and up are 455*34615Smarc * used to specify the QDSS device number (ie: which one?) */ 45630391Skarels 45730391Skarels 45830391Skarels #define CONS 0 45930391Skarels #define ALTCONS 1 46030391Skarels #define GRAPHIC 2 46130391Skarels 462*34615Smarc /*---------------------------------------------- 463*34615Smarc * console cursor bitmap (block cursor type) */ 46430391Skarels 46530391Skarels short cons_cursor[32] = { /* white block cursor */ 46630391Skarels 46730391Skarels /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 46830391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 46930391Skarels /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 47030391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 47130391Skarels 47230391Skarels }; 47330391Skarels 474*34615Smarc /*------------------------------------- 475*34615Smarc * constants used in font operations */ 47630391Skarels 477*34615Smarc 478*34615Smarc /* Originaly this was CHARS 95 */ 479*34615Smarc #define CHARS 190 /* # of chars in the font */ 480*34615Smarc 48130391Skarels #define CHAR_HEIGHT 15 /* char height in pixels */ 48230391Skarels #define CHAR_WIDTH 8 /* char width in pixels*/ 48330391Skarels #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ 48430391Skarels #define ROWS CHAR_HEIGHT 48530391Skarels 48630391Skarels 48730391Skarels #define FONT_X 0 /* font's off screen adrs */ 48830391Skarels #define FONT_Y (2048 - CHAR_HEIGHT) 48930391Skarels 490*34615Smarc /* Offset to second row characters */ 491*34615Smarc #define FONT_OFFSET ((MAX_SCREEN_X/CHAR_WIDTH)*CHAR_HEIGHT) 49230391Skarels 493*34615Smarc extern char q_font[]; /* reference font object code */ 49430391Skarels 495*34615Smarc extern u_short q_key[]; /* reference key xlation tables */ 496*34615Smarc extern u_short q_shift_key[]; 497*34615Smarc extern char *q_special[]; 49830391Skarels 499*34615Smarc /*-------------------------------------------------- 500*34615Smarc * definitions for cursor acceleration reporting */ 501*34615Smarc 50230391Skarels #define ACC_OFF 0x01 /* acceleration is inactive */ 50330391Skarels 504*34615Smarc /*-------------------------------------------------------------------------- 505*34615Smarc * v_consputc is the switch that is used to redirect the console cnputc() to 506*34615Smarc * the virtual console qdputc(). 507*34615Smarc * v_consgetc is the switch that is used to redirect the console getchar() to 508*34615Smarc * the virtual console qdgetc(). 509*34615Smarc */ 51030391Skarels 511*34615Smarc #ifdef notdef 512*34615Smarc extern (*v_consputc)(); 513*34615Smarc int qdputc(); /* used to direct kernel console output */ 514*34615Smarc extern (*v_consgetc)(); 515*34615Smarc int qdgetc(); /* used to read kernel console input */ 51630391Skarels 517*34615Smarc int qdstart(); /* used to direct /dev/console output */ 518*34615Smarc #endif 519*34615Smarc extern (*v_putc)(); 520*34615Smarc extern struct cdevsw *consops; 521*34615Smarc int qdputc(); 522*34615Smarc int qdstart(); 52330391Skarels 524*34615Smarc /*------------------------------------------------------------------------ 525*34615Smarc * LK-201 state storage for input console keyboard conversion to ASCII */ 52630391Skarels 527*34615Smarc struct q_keyboard { 528*34615Smarc 529*34615Smarc int shift; /* state variables */ 530*34615Smarc int cntrl; 531*34615Smarc int lock; 532*34615Smarc int lastcode; /* last keycode typed */ 533*34615Smarc unsigned kup[8]; /* bits for each keycode*/ 534*34615Smarc unsigned dkeys[8]; /* down/up mode keys */ 535*34615Smarc char last; /* last character */ 536*34615Smarc 537*34615Smarc } q_keyboard; 538*34615Smarc 539*34615Smarc /*-------------------------------------------------- 540*34615Smarc * ULTRIX settings for first open. */ 541*34615Smarc 542*34615Smarc #define IFLAGS (EVENP|ECHO|XTABS|CRMOD) 543*34615Smarc 544*34615Smarc /*------------------------------------------------------------------------ 545*34615Smarc * termio flags will be set to these default values in non-termio mode to 546*34615Smarc * provide a backward compatible ULTRIX environment. */ 547*34615Smarc 548*34615Smarc #ifdef POSIXTTY 549*34615Smarc #define IFLAG (BRKINT|ISTRIP|IXON|IXANY|ICRNL|IEXTEN|IMAXBEL) 550*34615Smarc #define OFLAG (OPOST|OXTABS|ONLCR) 551*34615Smarc #define LFLAG (ISIG|ICANON|ECHO) 552*34615Smarc #define CFLAG (PARENB|CREAD|CS7|CLOCAL) 553*34615Smarc #endif 554*34615Smarc 555*34615Smarc /***************************************************************** 556*34615Smarc ****************************************************************** 557*34615Smarc ****************************************************************** 558*34615Smarc * 559*34615Smarc * DRIVER FUNCTIONS START HERE: 560*34615Smarc * 561*34615Smarc ****************************************************************** 562*34615Smarc ****************************************************************** 563*34615Smarc *****************************************************************/ 564*34615Smarc 56530391Skarels /********************************************************************* 56630391Skarels * 567*34615Smarc * qdcons_init()... init QDSS as console (before probe routine) 56830391Skarels * 56930391Skarels *********************************************************************/ 57030391Skarels 57130391Skarels qdcons_init() 57230391Skarels { 57330391Skarels register u_int unit; 57430391Skarels 57530391Skarels int *ptep; /* page table entry pointer */ 57630391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 577*34615Smarc u_int mapix; /* index into QVmap[] array */ 57830391Skarels 579*34615Smarc struct percpu *pcpu; /* pointer to cpusw structure */ 580*34615Smarc register struct qbus *qb; 58130391Skarels u_short *qdaddr; /* address of QDSS IO page CSR */ 58230391Skarels u_short *devptr; /* vitual device space */ 583*34615Smarc extern cnputc(); 58430391Skarels 58530391Skarels #define QDSSCSR 0x1F00 58630391Skarels 58732012Smarc if (v_putc != cnputc) 58832012Smarc return; 58932012Smarc 59030391Skarels unit = 0; 59130391Skarels 592*34615Smarc /*---------------------------------------------------- 593*34615Smarc * find the cpusw entry that matches this machine. */ 59430391Skarels 59532012Smarc for (pcpu = percpu; pcpu && pcpu->pc_cputype != cpu; pcpu++) 59632012Smarc ; 59732012Smarc if (pcpu == NULL) 59832012Smarc return; 59930391Skarels 600*34615Smarc #ifdef notdef /* the ultrix way */ 601*34615Smarc /*------------------------------------------------------ 602*34615Smarc * Map the Q-bus memory space into the system memory. */ 60330391Skarels 604*34615Smarc ubaaccess(((*cpup->v_umaddr)(0)), QVmap[0], 605*34615Smarc cpup->pc_umsize, PG_V | PG_KW); 606*34615Smarc 607*34615Smarc ubaaccess(((*cpup->v_udevaddr)(0)), QVmap[0]+btop(cpup->pc_umsize), 608*34615Smarc DEVSPACESIZE ,PG_V|PG_KW); 609*34615Smarc 610*34615Smarc /*--------------------------------------------------------------------- 611*34615Smarc * map the QDSS into the Qbus memory (which is now in system space) */ 612*34615Smarc 613*34615Smarc devptr = (u_short *)((char *)qvmem[0]+cpup->pc_umsize); 614*34615Smarc qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 615*34615Smarc 616*34615Smarc if (BADADDR(qdaddr, sizeof(short))) 617*34615Smarc return(0); 618*34615Smarc 619*34615Smarc /*--------------------------------------------------- 620*34615Smarc * tell QDSS which Q memory address base to decode */ 621*34615Smarc 622*34615Smarc mapix = (int) VTOP(QMEMSIZE - CHUNK); 623*34615Smarc ptep = (int *) QVmap[0] + mapix; 624*34615Smarc phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 625*34615Smarc *qdaddr = (u_short) ((int)phys_adr >> 16); 626*34615Smarc 627*34615Smarc qdflags[unit].config = *(u_short *)qdaddr; 628*34615Smarc 629*34615Smarc #endif /*notdef*/ 630*34615Smarc 631*34615Smarc /* the BSD way */ 63232012Smarc /* 633*34615Smarc * Map device registers - the last 8K of qvmem. 63432012Smarc */ 63532012Smarc qb = (struct qbus *)pcpu->pc_io->io_details; 63632012Smarc ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize, 63732012Smarc UBAIOPAGES * NBPG); 63830391Skarels 63932012Smarc devptr = (u_short *)((char *)umem[0]+(qb->qb_memsize * NBPG)); 64030391Skarels qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 64132012Smarc if (badaddr(qdaddr, sizeof(short))) { 642*34615Smarc printf("Can't find qdss (badaddr)\n"); /* debug */ 64330391Skarels return(0); 64432012Smarc } 645*34615Smarc 646*34615Smarc 647*34615Smarc 64832012Smarc /* 64932012Smarc * Map q-bus memory used by qdss. (separate map) 65032012Smarc */ 65132012Smarc mapix = QMEMSIZE - (CHUNK * (unit + 1)); 65232012Smarc phys_adr = qb->qb_maddr + mapix; 65332012Smarc ioaccess(phys_adr, QVmap[0], (CHUNK*NQD)); 65430391Skarels 65532012Smarc /* 65632012Smarc * tell QDSS which Q memory address base to decode 65732012Smarc */ 65830391Skarels 65932012Smarc /* 66032012Smarc * shifted right 16 bits - its in 64K units 66132012Smarc */ 66232012Smarc *qdaddr = (u_short)((int)mapix >> 16); 66330391Skarels qdflags[unit].config = *(u_short *)qdaddr; 66430391Skarels 665*34615Smarc /*---------------------------------------------------------------------- 666*34615Smarc * load qdmap struct with the virtual addresses of the QDSS elements */ 66730391Skarels 668*34615Smarc #ifdef notdef /*ultrix way */ 669*34615Smarc qdbase[unit] = (caddr_t) (qvmem[0] + QMEMSIZE - CHUNK); 670*34615Smarc #endif 67130391Skarels 672*34615Smarc qdbase[unit] = (caddr_t) (qvmem[0]); 673*34615Smarc 67430391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 67530391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 67630391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 67730391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 67830391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 67930391Skarels qdmap[unit].red = qdbase[unit] + RED; 68030391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 68130391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 68230391Skarels 68330391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 68430391Skarels 685*34615Smarc /*------------------ 686*34615Smarc * init the QDSS */ 68730391Skarels 68832012Smarc printf("qdbase[0] = %x, qdmap[0].memcsr = %x\n", 689*34615Smarc (char *)qdbase[0], qdmap[0].memcsr); 69032012Smarc 69130391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */ 69230391Skarels 69330391Skarels cursor[unit].x = 0; 69430391Skarels cursor[unit].y = 0; 69530391Skarels init_shared(unit); /* init shared memory */ 69630391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 69730391Skarels clear_qd_screen(unit); /* clear the screen */ 69830391Skarels ldfont(unit); /* load the console font */ 69930391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 70030391Skarels setup_input(unit); /* init the DUART */ 70130391Skarels 702*34615Smarc /*---------------------------------------------------- 703*34615Smarc * smash the system's virtual console address table */ 704*34615Smarc 705*34615Smarc #ifdef notdef /* the ultrix way */ 706*34615Smarc v_consputc = qdputc; 707*34615Smarc v_consgetc = qdgetc; 708*34615Smarc cdevsw[0] = cdevsw[QDSSMAJOR]; 709*34615Smarc #endif 710*34615Smarc /* the bsd way */ 71132012Smarc v_putc = qdputc; 71232012Smarc consops = &cdevsw[QDSSMAJOR]; 71330391Skarels 714*34615Smarc ws_display_type = QDSSMAJOR; /* Idenify QDSS as graphics device */ 71530391Skarels return(1); 71630391Skarels 71730391Skarels } /* qdcons_init */ 71830391Skarels 71930391Skarels /********************************************************************* 72030391Skarels * 72130391Skarels * qdprobe()... configure QDSS into Q memory and make it intrpt 72230391Skarels * 72330391Skarels ********************************************************************** 72430391Skarels * 72530391Skarels * calling convention: 72630391Skarels * qdprobe(reg, ctlr); 72730391Skarels * caddr_t reg; 72830391Skarels * int ctlr; 72930391Skarels * 73030391Skarels * where: reg - a character pointer to the QDSS I/O page register 73130391Skarels * ctlr - controller number (?) 73230391Skarels * 73330391Skarels * side effects: QDSS gets mapped into Qbus memory space at the first 73430391Skarels * vacant 64kb boundary counting back from the top of 735*34615Smarc * Qbus memory space (qvmem+4mb) 73630391Skarels * 73730391Skarels * return: QDSS bus request level and vector address returned in 73830391Skarels * registers by UNIX convention. 73930391Skarels * 74030391Skarels *****************/ 74130391Skarels 74230391Skarels qdprobe(reg) 74330391Skarels caddr_t reg; 74430391Skarels { 745*34615Smarc register int br, cvec; /* value-result */ 74630391Skarels 74730391Skarels register int unit; 74830391Skarels 74930391Skarels struct dga *dga; /* pointer to gate array structure */ 75030391Skarels struct cpusw *cpup; /* pointer to the cpusw structure */ 75130391Skarels 75230391Skarels int *ptep; /* page table entry pointer */ 75330391Skarels int vector; 75430391Skarels 75530391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 75630391Skarels u_int mapix; 75730391Skarels 758*34615Smarc /*--------------------------------------------------------------- 759*34615Smarc * calculate board unit number from I/O page register address */ 76030391Skarels 76130391Skarels unit = (int) (((int)reg >> 1) & 0x0007); 76230391Skarels 763*34615Smarc /*--------------------------------------------------------------------------- 76430391Skarels * QDSS regs must be mapped to Qbus memory space at a 64kb physical boundary. 76530391Skarels * The Qbus memory space is mapped into the system memory space at config 766*34615Smarc * time. After config runs, "qvmem[0]" (ubavar.h) holds the system virtual adrs 76730391Skarels * of the start of Qbus memory. The Qbus memory page table is found via 768*34615Smarc * an array of pte ptrs called "QVmap[]" (ubavar.h) which is also loaded at 76930391Skarels * config time. These are the variables used below to find a vacant 64kb 77030391Skarels * boundary in Qbus memory, and load it's corresponding physical adrs into 771*34615Smarc * the QDSS's I/O page CSR. */ 77230391Skarels 773*34615Smarc /* 774*34615Smarc * Only if QD is the graphics device. 775*34615Smarc */ 776*34615Smarc 777*34615Smarc if (ws_display_type && (ws_display_type != QDSSMAJOR)) 778*34615Smarc return(0); 779*34615Smarc 78030391Skarels /* if this QDSS is NOT the console, then do init here.. */ 78130391Skarels 782*34615Smarc if (unit != 0) { 783*34615Smarc printf("qd: can't support two qdss's (yet)\n"); 784*34615Smarc #ifdef notdef /* notyet */ 78530391Skarels if (v_consputc != qdputc || unit != 0) { 78630391Skarels 787*34615Smarc /*------------------------- 788*34615Smarc * read QDSS config info */ 789*34615Smarc 79030391Skarels qdflags[unit].config = *(u_short *)reg; 79130391Skarels 792*34615Smarc /*------------------------------------ 793*34615Smarc * find an empty 64kb adrs boundary */ 79430391Skarels 795*34615Smarc qdbase[unit] = (caddr_t) (qvmem[0] + QMEMSIZE - CHUNK); 796*34615Smarc 797*34615Smarc /*---------------------------------------------------- 798*34615Smarc * find the cpusw entry that matches this machine. */ 799*34615Smarc 80030391Skarels cpup = &cpusw[cpu]; 80130391Skarels while ( !(BADADDR(qdbase[unit], sizeof(short))) ) 80230391Skarels qdbase[unit] -= CHUNK; 80330391Skarels 804*34615Smarc /*--------------------------------------------------- 805*34615Smarc * tell QDSS which Q memory address base to decode */ 806*34615Smarc 807*34615Smarc mapix = (int) (VTOP(qdbase[unit]) - VTOP(qvmem[0])); 808*34615Smarc ptep = (int *) QVmap[0] + mapix; 80930391Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 81030391Skarels *(u_short *)reg = (u_short) ((int)phys_adr >> 16); 81130391Skarels 812*34615Smarc /*----------------------------------------------------------- 813*34615Smarc * load QDSS adrs map with system addresses of device regs */ 814*34615Smarc 81530391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 81630391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 81730391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 81830391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 81930391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 82030391Skarels qdmap[unit].red = qdbase[unit] + RED; 82130391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 82230391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 82330391Skarels 82430391Skarels /* device init */ 82530391Skarels 82630391Skarels cursor[unit].x = 0; 82730391Skarels cursor[unit].y = 0; 82830391Skarels init_shared(unit); /* init shared memory */ 82930391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 83030391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 83130391Skarels setup_input(unit); /* init the DUART */ 83230391Skarels clear_qd_screen(unit); 83330391Skarels ldfont(unit); /* load the console font */ 83430391Skarels 83530391Skarels /* once only: turn on sync */ 83630391Skarels 83730391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; 838*34615Smarc #endif /*notdef*/ 83930391Skarels } 84030391Skarels 841*34615Smarc /*-------------------------------------------------------------------------- 842*34615Smarc * the QDSS interrupts at HEX vectors xx0 (DMA) xx4 (ADDER) and xx8 (DUART). 843*34615Smarc * Therefore, we take three vectors from the vector pool, and then continue 844*34615Smarc * to take them until we get a xx0 HEX vector. The pool provides vectors 845*34615Smarc * in contiguous decending order. */ 84630391Skarels 84730391Skarels vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ 84830391Skarels 84930391Skarels while (vector & 0x0F) { /* if lo nibble != 0.. */ 85030391Skarels vector = (uba_hd[0].uh_lastiv -= 4); /* ..take another vector */ 85130391Skarels } 85230391Skarels 853*34615Smarc /*--------------------------------------------------------- 854*34615Smarc * setup DGA to do a DMA interrupt (transfer count = 0) */ 85530391Skarels 85630391Skarels dga = (struct dga *) qdmap[unit].dga; 85730391Skarels 85830391Skarels dga->csr = (short) HALT; /* disable everything */ 85930391Skarels dga->ivr = (short) vector; /* load intrpt base vector */ 86030391Skarels dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ 86130391Skarels dga->bytcnt_hi = (short) 0; 86230391Skarels 86330391Skarels /* turn on DMA interrupts */ 86430391Skarels 86530391Skarels dga->csr &= ~SET_DONE_FIFO; 86630391Skarels dga->csr |= DMA_IE | DL_ENB; 86730391Skarels 86830391Skarels DELAY(20000); /* wait for the intrpt */ 86930391Skarels 87030391Skarels dga->csr = HALT; /* stop the wheels */ 87130391Skarels 872*34615Smarc /*---------- 873*34615Smarc * exits */ 874*34615Smarc 87530391Skarels if (cvec != vector) /* if vector != base vector.. */ 87630391Skarels return(0); /* ..return = 'no device' */ 87730391Skarels 878*34615Smarc /* 879*34615Smarc * score this as an existing qdss 880*34615Smarc */ 881*34615Smarc qdcount++; 882*34615Smarc ws_display_units |= (1 << unit); 883*34615Smarc 88430391Skarels return(sizeof(short)); /* return size of QDSS I/O page reg */ 88530391Skarels 88630391Skarels } /* qdprobe */ 88730391Skarels 88830391Skarels /***************************************************************** 88930391Skarels * 890*34615Smarc * qdattach()... do the one-time initialization 89130391Skarels * 89230391Skarels ****************************************************************** 89330391Skarels * 89430391Skarels * calling convention: 89530391Skarels * qdattach(ui); 89630391Skarels * struct uba_device *ui; 89730391Skarels * 89830391Skarels * where: ui - pointer to the QDSS's uba_device structure 89930391Skarels * 90030391Skarels * side effects: none 90130391Skarels * return: none 90230391Skarels * 90330391Skarels *************************/ 90430391Skarels 90530391Skarels qdattach(ui) 90630391Skarels struct uba_device *ui; 90730391Skarels { 90830391Skarels register u_int unit; /* QDSS module # for this call */ 90930391Skarels 91030391Skarels unit = ui->ui_unit; /* get QDSS number */ 91130391Skarels 912*34615Smarc /*---------------------------------- 913*34615Smarc * init "qdflags[]" for this QDSS */ 91430391Skarels 91530391Skarels qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ 91630391Skarels qdflags[unit].mapped = 0; 917*34615Smarc qdflags[unit].kernel_loop = -1; 91830391Skarels qdflags[unit].user_dma = 0; 91930391Skarels qdflags[unit].curs_acc = ACC_OFF; 92030391Skarels qdflags[unit].curs_thr = 128; 92130391Skarels qdflags[unit].tab_res = 2; /* default tablet resolution factor */ 92230391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 92330391Skarels qdflags[unit].adder_ie = 0; 92430391Skarels 925*34615Smarc /*---------------------------------------------------------------------- 926*34615Smarc * init structures used in kbd/mouse interrupt service. This code must 927*34615Smarc * come after the "init_shared()" routine has run since that routine inits 928*34615Smarc * the eq_header[unit] structure used here. */ 92930391Skarels 930*34615Smarc /*-------------------------------------------- 931*34615Smarc * init the "latest mouse report" structure */ 93230391Skarels 93330391Skarels last_rep[unit].state = 0; 93430391Skarels last_rep[unit].dx = 0; 93530391Skarels last_rep[unit].dy = 0; 93630391Skarels last_rep[unit].bytcnt = 0; 93730391Skarels 938*34615Smarc /*------------------------------------------------ 939*34615Smarc * init the event queue (except mouse position) */ 94030391Skarels 94130391Skarels eq_header[unit]->header.events = (struct _vs_event *) 94230391Skarels ((int)eq_header[unit] 94330391Skarels + sizeof(struct qdinput)); 94430391Skarels 94530391Skarels eq_header[unit]->header.size = MAXEVENTS; 94630391Skarels eq_header[unit]->header.head = 0; 94730391Skarels eq_header[unit]->header.tail = 0; 94830391Skarels 949*34615Smarc /*------------------------------------------ 950*34615Smarc * init single process access lock switch */ 95130391Skarels 95230391Skarels one_only[unit] = 0; 95330391Skarels 95430391Skarels } /* qdattach */ 95530391Skarels 95630391Skarels /*************************************************************** 95730391Skarels * 958*34615Smarc * qdopen()... open a minor device 95930391Skarels * 96030391Skarels **************************************************************** 96130391Skarels * 96230391Skarels * calling convention: qdopen(dev, flag); 96330391Skarels * dev_t dev; 96430391Skarels * int flag; 96530391Skarels * 96630391Skarels * side effects: none 96730391Skarels * 96830391Skarels *********************/ 96930391Skarels 97030391Skarels qdopen(dev, flag) 97130391Skarels dev_t dev; 97230391Skarels int flag; 97330391Skarels { 97430391Skarels register struct uba_device *ui; /* ptr to uba structures */ 97530391Skarels register struct dga *dga; /* ptr to gate array struct */ 97630391Skarels register struct tty *tp; 97730391Skarels 97830391Skarels struct adder *adder; 97930391Skarels struct duart *duart; 98030391Skarels 98130391Skarels u_int unit; 98230391Skarels u_int minor_dev; 98330391Skarels int s; 98430391Skarels 98530391Skarels minor_dev = minor(dev); /* get QDSS minor device number */ 98630391Skarels unit = minor_dev >> 2; 98730391Skarels 988*34615Smarc /*--------------------------------- 989*34615Smarc * check for illegal conditions */ 99030391Skarels 99130391Skarels ui = qdinfo[unit]; /* get ptr to QDSS device struct */ 99230391Skarels 99330391Skarels if (ui == 0 || ui->ui_alive == 0) 99430391Skarels return(ENXIO); /* no such device or address */ 99530391Skarels 996*34615Smarc /*-------------- 997*34615Smarc * init stuff */ 99830391Skarels 99930391Skarels adder = (struct adder *) qdmap[unit].adder; 100030391Skarels duart = (struct duart *) qdmap[unit].duart; 100130391Skarels dga = (struct dga *) qdmap[unit].dga; 100230391Skarels 1003*34615Smarc /*------------------------------------ 1004*34615Smarc * if this is the graphic device... */ 100530391Skarels 100630391Skarels if ((minor_dev & 0x03) == 2) { 100730391Skarels 100830391Skarels if (one_only[unit] != 0) 100930391Skarels return(EBUSY); 101030391Skarels else 101130391Skarels one_only[unit] = 1; 101230391Skarels 101330391Skarels qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ 101430391Skarels 101530391Skarels /* enble kbd & mouse intrpts in DUART mask reg */ 101630391Skarels 101730391Skarels qdflags[unit].duart_imask |= 0x22; 101830391Skarels duart->imask = qdflags[unit].duart_imask; 101930391Skarels 1020*34615Smarc /*------------------------------------------------------------------ 1021*34615Smarc * if the open call is to the console or the alternate console... */ 102230391Skarels 1023*34615Smarc } else if ((minor_dev & 0x03) != 2) { 1024*34615Smarc 102530391Skarels qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ 102630391Skarels dga->csr |= CURS_ENB; 102730391Skarels 102830391Skarels qdflags[unit].duart_imask |= 0x02; 102930391Skarels duart->imask = qdflags[unit].duart_imask; 103030391Skarels 103130391Skarels /*------------------------------- 103230391Skarels * some setup for tty handling */ 103330391Skarels 103430391Skarels tp = &qd_tty[minor_dev]; 103530391Skarels 103630391Skarels tp->t_addr = ui->ui_addr; 103730391Skarels tp->t_oproc = qdstart; 1038*34615Smarc #ifdef notdef /* never */ 1039*34615Smarc /*--------------------------------------------------------------------- 1040*34615Smarc * Look at the compatibility mode to specify correct default parameters 1041*34615Smarc * and to insure only standard specified functionality. */ 1042*34615Smarc if ((u.u_procp->p_progenv == A_SYSV) || 1043*34615Smarc (u.u_procp->p_progenv == A_POSIX)) { 1044*34615Smarc flag |= O_TERMIO; 1045*34615Smarc tp->t_line = TERMIODISC; 1046*34615Smarc } 1047*34615Smarc #endif /*notdef*/ 104830391Skarels 104930391Skarels if ((tp->t_state & TS_ISOPEN) == 0) { 105030391Skarels 105130391Skarels ttychars(tp); 1052*34615Smarc tp->t_flags = IFLAGS; 105330391Skarels tp->t_ispeed = B9600; 105430391Skarels tp->t_ospeed = B9600; 1055*34615Smarc tp->t_state = TS_ISOPEN | TS_CARR_ON; 105630391Skarels 1057*34615Smarc #ifdef notdef /* never */ 1058*34615Smarc tp->t_cflag = tp->t_cflag_ext = B9600; 1059*34615Smarc tp->t_iflag_ext = 0; 1060*34615Smarc tp->t_oflag_ext = 0; 1061*34615Smarc tp->t_lflag_ext = 0; 1062*34615Smarc 1063*34615Smarc if( (minor_dev & 0x03) == 0 ) { 1064*34615Smarc /*---------------------------------------------------- 1065*34615Smarc * Ultrix defaults to a "COOKED" mode on the first 1066*34615Smarc * open, while termio defaults to a "RAW" style. 1067*34615Smarc * Base this decision by a flag set in the termio 1068*34615Smarc * emulation routine for open, or set by an explicit 1069*34615Smarc * ioctl call. */ 1070*34615Smarc 1071*34615Smarc if ( flag & O_TERMIO ) { 1072*34615Smarc /*-------------------------------------- 1073*34615Smarc * Provide a termio style environment. 1074*34615Smarc * "RAW" style by default. */ 1075*34615Smarc 1076*34615Smarc tp->t_flags = RAW; 1077*34615Smarc tp->t_iflag = 0; 1078*34615Smarc tp->t_oflag = 0; 1079*34615Smarc tp->t_cflag |= CS8|CREAD|HUPCL; 1080*34615Smarc tp->t_lflag = 0; 1081*34615Smarc 1082*34615Smarc /*------------------------------------- 1083*34615Smarc * Change to System V line discipline.*/ 1084*34615Smarc 1085*34615Smarc tp->t_line = TERMIODISC; 1086*34615Smarc /*----------------------------------------- 1087*34615Smarc * The following three control chars have 1088*34615Smarc * different default values than ULTRIX. */ 1089*34615Smarc 1090*34615Smarc tp->t_cc[VERASE] = '#'; 1091*34615Smarc tp->t_cc[VKILL] = '@'; 1092*34615Smarc tp->t_cc[VINTR] = 0177; 1093*34615Smarc tp->t_cc[VMIN] = 6; 1094*34615Smarc tp->t_cc[VTIME] = 1; 1095*34615Smarc } else { 1096*34615Smarc /*-------------------------------------- 1097*34615Smarc * Provide a backward compatible ULTRIX 1098*34615Smarc * environment. "COOKED" style. */ 1099*34615Smarc 1100*34615Smarc tp->t_flags = IFLAGS; 1101*34615Smarc tp->t_iflag = IFLAG; 1102*34615Smarc tp->t_oflag = OFLAG; 1103*34615Smarc tp->t_lflag = LFLAG; 1104*34615Smarc tp->t_cflag |= CFLAG; 1105*34615Smarc } 110632012Smarc } 110732012Smarc else { 110830391Skarels tp->t_flags = RAW; 1109*34615Smarc tp->t_iflag = 0; 1110*34615Smarc tp->t_oflag = 0; 1111*34615Smarc tp->t_cflag |= CS8|CREAD|HUPCL; 1112*34615Smarc tp->t_lflag = 0; 111332012Smarc } 1114*34615Smarc if( (minor_dev & 0x03) == 1 ) 1115*34615Smarc tp->t_iflag |= IXOFF; /* flow control for qconsole */ 1116*34615Smarc #endif /*notdef*/ 111730391Skarels } 111830391Skarels 111930391Skarels /*---------------------------------------- 112030391Skarels * enable intrpts, open line discipline */ 112130391Skarels 112230391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 112330391Skarels return ((*linesw[tp->t_line].l_open)(dev, tp)); 112430391Skarels } 112530391Skarels 112630391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 112730391Skarels return(0); 112830391Skarels 112930391Skarels } /* qdopen */ 113030391Skarels 113130391Skarels /*************************************************************** 113230391Skarels * 1133*34615Smarc * qdclose()... clean up on the way out 113430391Skarels * 113530391Skarels **************************************************************** 113630391Skarels * 113730391Skarels * calling convention: qdclose(); 113830391Skarels * 113930391Skarels * side effects: none 114030391Skarels * 114130391Skarels * return: none 114230391Skarels * 114330391Skarels *********************/ 114430391Skarels 114530391Skarels qdclose(dev, flag) 114630391Skarels dev_t dev; 114730391Skarels int flag; 114830391Skarels { 114930391Skarels register struct tty *tp; 115030391Skarels register struct qdmap *qd; 115130391Skarels register int *ptep; 115230391Skarels int i; /* SIGNED index */ 115330391Skarels 115430391Skarels struct dga *dga; /* gate array register map pointer */ 115530391Skarels struct duart *duart; 115630391Skarels struct adder *adder; 115730391Skarels 115830391Skarels u_int unit; 115930391Skarels u_int minor_dev; 116030391Skarels u_int mapix; 116130391Skarels 116230391Skarels minor_dev = minor(dev); /* get minor device number */ 116330391Skarels unit = minor_dev >> 2; /* get QDSS number */ 116430391Skarels qd = &qdmap[unit]; 116530391Skarels 1166*34615Smarc /*------------------------------------ 1167*34615Smarc * if this is the graphic device... */ 116830391Skarels 116930391Skarels if ((minor_dev & 0x03) == 2) { 1170*34615Smarc 1171*34615Smarc /*----------------- 1172*34615Smarc * unlock driver */ 1173*34615Smarc 1174*34615Smarc if (one_only[unit] != 1) 117530391Skarels return(EBUSY); 117630391Skarels else 117730391Skarels one_only[unit] = 0; 117830391Skarels 1179*34615Smarc /*---------------------------- 1180*34615Smarc * re-protect device memory */ 118130391Skarels 118230391Skarels if (qdflags[unit].mapped & MAPDEV) { 118330391Skarels 1184*34615Smarc /*---------------- 1185*34615Smarc * TEMPLATE RAM */ 118630391Skarels 118732012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 118832012Smarc ptep = (int *)(QVmap[0] + mapix); 118930391Skarels 119030391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 119130391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 119230391Skarels 1193*34615Smarc /*--------- 1194*34615Smarc * ADDER */ 119530391Skarels 119632012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 119732012Smarc ptep = (int *)(QVmap[0] + mapix); 119830391Skarels 119930391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 120030391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 120130391Skarels 1202*34615Smarc /*-------------- 1203*34615Smarc * COLOR MAPS */ 120430391Skarels 120532012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 120632012Smarc ptep = (int *)(QVmap[0] + mapix); 120730391Skarels 120830391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 120930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 121030391Skarels } 121130391Skarels 1212*34615Smarc /*---------------------------------------------------- 1213*34615Smarc * re-protect DMA buffer and free the map registers */ 121430391Skarels 121530391Skarels if (qdflags[unit].mapped & MAPDMA) { 121630391Skarels 121730391Skarels dga = (struct dga *) qdmap[unit].dga; 121830391Skarels adder = (struct adder *) qdmap[unit].adder; 121930391Skarels 122030391Skarels dga->csr &= ~DMA_IE; 122130391Skarels dga->csr &= ~0x0600; /* kill DMA */ 122230391Skarels adder->command = CANCEL; 122330391Skarels 122430391Skarels /* if DMA was running, flush spurious intrpt */ 122530391Skarels 122630391Skarels if (dga->bytcnt_lo != 0) { 122730391Skarels dga->bytcnt_lo = 0; 122830391Skarels dga->bytcnt_hi = 0; 122930391Skarels DMA_SETIGNORE(DMAheader[unit]); 123030391Skarels dga->csr |= DMA_IE; 123130391Skarels dga->csr &= ~DMA_IE; 123230391Skarels } 123330391Skarels 123430391Skarels ptep = (int *) 123530391Skarels ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); 123630391Skarels 123730391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 123830391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 123930391Skarels 124030391Skarels ubarelse(0, &Qbus_unmap[unit]); 124130391Skarels } 124230391Skarels 1243*34615Smarc /*--------------------------------------- 1244*34615Smarc * re-protect 1K (2 pages) event queue */ 124530391Skarels 124630391Skarels if (qdflags[unit].mapped & MAPEQ) { 124730391Skarels 124830391Skarels ptep = (int *) 124930391Skarels ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); 125030391Skarels 125130391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 125230391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 125330391Skarels } 125430391Skarels 1255*34615Smarc /*------------------------------------------------------------ 1256*34615Smarc * re-protect scroll param area and disable scroll intrpts */ 125730391Skarels 125830391Skarels if (qdflags[unit].mapped & MAPSCR) { 125930391Skarels 126030391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 126130391Skarels + (mfpr(SBR) | 0x80000000)); 126230391Skarels 126330391Skarels /* re-protect 512 scroll param area */ 126430391Skarels 126530391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 126630391Skarels 126730391Skarels adder = (struct adder *) qdmap[unit].adder; 126830391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 126930391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 127030391Skarels } 127130391Skarels 1272*34615Smarc /*----------------------------------------------------------- 1273*34615Smarc * re-protect color map write buffer area and kill intrpts */ 127430391Skarels 127530391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 127630391Skarels 127730391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 127830391Skarels + (mfpr(SBR) | 0x80000000)); 127930391Skarels 128030391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 128130391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 128230391Skarels 128330391Skarels color_buf[unit]->status = 0; 128430391Skarels 128530391Skarels adder = (struct adder *) qdmap[unit].adder; 128630391Skarels qdflags[unit].adder_ie &= ~VSYNC; 128730391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 128830391Skarels } 128930391Skarels 1290*34615Smarc /*----------------------------------- 1291*34615Smarc * flag that everthing is unmapped */ 129230391Skarels 1293*34615Smarc mtpr(TBIA, 0); /* smash CPU's translation buf */ 1294*34615Smarc qdflags[unit].mapped = 0; /* flag everything now unmapped */ 129530391Skarels qdflags[unit].inuse &= ~GRAPHIC_DEV; 129630391Skarels qdflags[unit].curs_acc = ACC_OFF; 129730391Skarels qdflags[unit].curs_thr = 128; 129830391Skarels 1299*34615Smarc /*--------------------- 1300*34615Smarc * restore the console */ 130130391Skarels 130230391Skarels dga = (struct dga *) qdmap[unit].dga; 130330391Skarels adder = (struct adder *) qdmap[unit].adder; 130430391Skarels 130530391Skarels dga->csr &= ~DMA_IE; 130630391Skarels dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ 130730391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 130830391Skarels adder->command = CANCEL; 130930391Skarels 131030391Skarels /* if DMA was running, flush spurious intrpt */ 131130391Skarels 131230391Skarels if (dga->bytcnt_lo != 0) { 131330391Skarels dga->bytcnt_lo = 0; 131430391Skarels dga->bytcnt_hi = 0; 131530391Skarels DMA_SETIGNORE(DMAheader[unit]); 131630391Skarels dga->csr |= DMA_IE; 131730391Skarels dga->csr &= ~DMA_IE; 131830391Skarels } 131930391Skarels 132030391Skarels init_shared(unit); /* init shared memory */ 132130391Skarels setup_dragon(unit); /* init ADDER/VIPER */ 132230391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 132330391Skarels setup_input(unit); /* init the DUART */ 132430391Skarels ldfont(unit); 132530391Skarels cursor[unit].x = 0; 132630391Skarels cursor[unit].y = 0; 132730391Skarels 1328*34615Smarc /* shut off the mouse rcv intrpt and turn on kbd intrpts */ 1329*34615Smarc 133030391Skarels duart = (struct duart *) qdmap[unit].duart; 133130391Skarels qdflags[unit].duart_imask &= ~(0x20); 133230391Skarels qdflags[unit].duart_imask |= 0x02; 133330391Skarels duart->imask = qdflags[unit].duart_imask; 1334*34615Smarc 1335*34615Smarc /*----------------------------------------- 1336*34615Smarc * shut off interrupts if all is closed */ 1337*34615Smarc 133830391Skarels if (!(qdflags[unit].inuse & (CONS_DEV | ALTCONS_DEV))) { 1339*34615Smarc 134030391Skarels dga = (struct dga *) qdmap[unit].dga; 134130391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 134230391Skarels } 134330391Skarels } 1344*34615Smarc 1345*34615Smarc /*---------------------------------------------------- 1346*34615Smarc * if this is the console or the alternate console */ 1347*34615Smarc 1348*34615Smarc else { 1349*34615Smarc 135030391Skarels tp = &qd_tty[minor_dev]; 135130391Skarels 135230391Skarels (*linesw[tp->t_line].l_close)(tp); 135330391Skarels ttyclose(tp); 1354*34615Smarc 135530391Skarels tp->t_state = 0; 1356*34615Smarc /* Remove termio flags that do not map */ 1357*34615Smarc #ifdef notdef /* never */ 1358*34615Smarc tp->t_iflag &= ~TERMIO_ONLY_IFLAG; 1359*34615Smarc tp->t_oflag &= ~TERMIO_ONLY_OFLAG; 1360*34615Smarc tp->t_cflag &= ~TERMIO_ONLY_CFLAG; 1361*34615Smarc tp->t_lflag &= ~TERMIO_ONLY_LFLAG; 1362*34615Smarc #endif /*notdef*/ 1363*34615Smarc 136430391Skarels qdflags[unit].inuse &= ~CONS_DEV; 1365*34615Smarc 1366*34615Smarc /*------------------------------------------------- 1367*34615Smarc * if graphics device is closed, kill interrupts */ 1368*34615Smarc 136930391Skarels if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { 137030391Skarels dga = (struct dga *) qdmap[unit].dga; 137130391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 137230391Skarels } 137330391Skarels } 137430391Skarels 1375*34615Smarc /*-------- 1376*34615Smarc * exit */ 1377*34615Smarc 137830391Skarels return(0); 137930391Skarels 138030391Skarels } /* qdclose */ 138130391Skarels 138230391Skarels /*************************************************************** 138330391Skarels * 1384*34615Smarc * qdioctl()... provide QDSS control services 138530391Skarels * 138630391Skarels **************************************************************** 138730391Skarels * 138830391Skarels * calling convention: qdioctl(dev, cmd, datap, flags); 138930391Skarels * 139030391Skarels * where: dev - the major/minor device number 139130391Skarels * cmd - the user-passed command argument 139230391Skarels * datap - ptr to user input buff (128 bytes max) 139330391Skarels * flags - "f_flags" from "struct file" in file.h 139430391Skarels * 139530391Skarels * 139630391Skarels * - here is the format for the input "cmd" argument 139730391Skarels * 139830391Skarels * 31 29 28 23 22 16 15 8 7 0 139930391Skarels * +----------------------------------------------------------------+ 140030391Skarels * |I/O type| | buff length | device ID char | user command | 140130391Skarels * +----------------------------------------------------------------+ 140230391Skarels * 140330391Skarels * Return data is in the data buffer pointed to by "datap" input spec 140430391Skarels * 140530391Skarels *********************/ 140630391Skarels 140730391Skarels qdioctl(dev, cmd, datap, flags) 140830391Skarels dev_t dev; 140930391Skarels int cmd; 141030391Skarels caddr_t datap; 141130391Skarels int flags; 141230391Skarels { 141330391Skarels register int *ptep; /* page table entry pointer */ 141432012Smarc register int mapix; /* QVmap[] page table index */ 141530391Skarels register struct _vs_event *event; 141630391Skarels register struct tty *tp; 1417*34615Smarc 141830391Skarels struct qdmap *qd; /* pointer to device map struct */ 141930391Skarels struct dga *dga; /* Gate Array reg structure pntr */ 142030391Skarels struct duart *duart; /* DUART reg structure pointer */ 142130391Skarels struct adder *adder; /* ADDER reg structure pointer */ 1422*34615Smarc 142330391Skarels struct prgkbd *cmdbuf; 142430391Skarels struct prg_cursor *curs; 142530391Skarels struct _vs_cursor *pos; 1426*34615Smarc 142730391Skarels u_int unit = minor(dev) >> 2; /* number of caller's QDSS */ 142830391Skarels u_int minor_dev = minor(dev); 142930391Skarels struct uba_device *ui = qdinfo[unit]; 143030391Skarels struct qd_softc *sc = &qd_softc[ui->ui_unit]; 1431*34615Smarc #ifdef notdef 1432*34615Smarc struct devget *devget; 1433*34615Smarc #endif 1434*34615Smarc 143530391Skarels int error; 143630391Skarels int s; 1437*34615Smarc 143830391Skarels int i; /* SIGNED index */ 143930391Skarels int sbr; /* SBR variable (you silly boy) */ 144030391Skarels u_int ix; 1441*34615Smarc 144230391Skarels short status; 144330391Skarels short *shortp; /* generic pointer to a short */ 144430391Skarels char *chrp; /* generic character pointer */ 1445*34615Smarc 144630391Skarels short *temp; /* a pointer to template RAM */ 144730391Skarels 1448*34615Smarc /*----------------------------------------- 1449*34615Smarc * service graphic device ioctl commands */ 1450*34615Smarc 145130391Skarels switch (cmd) { 1452*34615Smarc 1453*34615Smarc /*------------------------------------------------- 1454*34615Smarc * extract the oldest event from the event queue */ 1455*34615Smarc 145630391Skarels case QD_GETEVENT: 1457*34615Smarc 145830391Skarels if (ISEMPTY(eq_header[unit])) { 145930391Skarels event = (struct _vs_event *) datap; 146030391Skarels event->vse_device = VSE_NULL; 146130391Skarels break; 146230391Skarels } 1463*34615Smarc 146430391Skarels event = (struct _vs_event *) GETBEGIN(eq_header[unit]); 1465*34615Smarc s = spl5(); 146630391Skarels GETEND(eq_header[unit]); 146730391Skarels splx(s); 146830391Skarels bcopy(event, datap, sizeof(struct _vs_event)); 146930391Skarels break; 147030391Skarels 147130391Skarels /*------------------------------------------------------- 147230391Skarels * init the dragon stuff, DUART, and driver variables */ 147330391Skarels 147430391Skarels case QD_RESET: 147530391Skarels 147630391Skarels init_shared(unit); /* init shared memory */ 147730391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 147830391Skarels clear_qd_screen(unit); 147930391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 148030391Skarels ldfont(unit); /* load the console font */ 148130391Skarels setup_input(unit); /* init the DUART */ 148230391Skarels break; 148330391Skarels 148430391Skarels /*---------------------------------------- 148530391Skarels * init the DUART and driver variables */ 148630391Skarels 148730391Skarels case QD_SET: 148830391Skarels 148930391Skarels init_shared(unit); 149030391Skarels setup_input(unit); 149130391Skarels break; 149230391Skarels 149330391Skarels /*--------------------------------------------------------------- 149430391Skarels * clear the QDSS screen. (NOTE that this reinits the dragon) */ 149530391Skarels 149630391Skarels case QD_CLRSCRN: 149730391Skarels 1498*34615Smarc #ifdef notdef /* has caused problems and is not necessary */ 149930391Skarels setup_dragon(unit); 150030391Skarels clear_qd_screen(unit); 1501*34615Smarc #endif 150230391Skarels break; 150330391Skarels 150430391Skarels /*------------------------------------ 150530391Skarels * load a cursor into template RAM */ 150630391Skarels 150730391Skarels case QD_WTCURSOR: 150830391Skarels 150930391Skarels ldcursor(unit, datap); 151030391Skarels break; 151130391Skarels 151230391Skarels case QD_RDCURSOR: 151330391Skarels 151430391Skarels temp = (short *) qdmap[unit].template; 151530391Skarels 151630391Skarels /* cursor is 32 WORDS from the end of the 8k WORD... 151730391Skarels * ...template space */ 151830391Skarels 151930391Skarels temp += (8 * 1024) - 32; 152030391Skarels 152130391Skarels for (i = 0; i < 32; ++i, datap += sizeof(short)) 152230391Skarels *(short *)datap = *temp++; 152330391Skarels break; 152430391Skarels 152530391Skarels /*------------------------------ 152630391Skarels * position the mouse cursor */ 152730391Skarels 152830391Skarels case QD_POSCURSOR: 152930391Skarels 153030391Skarels dga = (struct dga *) qdmap[unit].dga; 153130391Skarels pos = (struct _vs_cursor *) datap; 1532*34615Smarc s = spl5(); 153330391Skarels dga->x_cursor = TRANX(pos->x); 153430391Skarels dga->y_cursor = TRANY(pos->y); 153530391Skarels eq_header[unit]->curs_pos.x = pos->x; 153630391Skarels eq_header[unit]->curs_pos.y = pos->y; 153730391Skarels splx(s); 153830391Skarels break; 153930391Skarels 154030391Skarels /*-------------------------------------- 154130391Skarels * set the cursor acceleration factor */ 154230391Skarels 154330391Skarels case QD_PRGCURSOR: 154430391Skarels 154530391Skarels curs = (struct prg_cursor *) datap; 1546*34615Smarc s = spl5(); 154730391Skarels qdflags[unit].curs_acc = curs->acc_factor; 154830391Skarels qdflags[unit].curs_thr = curs->threshold; 154930391Skarels splx(s); 155030391Skarels break; 155130391Skarels 155230391Skarels /*--------------------------------------- 155330391Skarels * enable 'user write' to device pages */ 155430391Skarels 155530391Skarels case QD_MAPDEVICE: 155630391Skarels 155730391Skarels /*-------------- 155830391Skarels * init stuff */ 155930391Skarels 156030391Skarels qdflags[unit].mapped |= MAPDEV; 156130391Skarels qd = (struct qdmap *) &qdmap[unit]; 156230391Skarels 156330391Skarels /*------------------------------------- 156430391Skarels * enable user write to template RAM */ 156530391Skarels 156632012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 156732012Smarc ptep = (int *)(QVmap[0] + mapix); 156830391Skarels 156930391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 157030391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 157130391Skarels 157230391Skarels /*---------------------------------- 157330391Skarels * enable user write to registers */ 157430391Skarels 157532012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 157632012Smarc ptep = (int *)(QVmap[0] + mapix); 157730391Skarels 157830391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 157930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 158030391Skarels 158130391Skarels /*----------------------------------- 158230391Skarels * enable user write to color maps */ 158330391Skarels 158432012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 158532012Smarc ptep = (int *)(QVmap[0] + mapix); 158630391Skarels 158730391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 158830391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 158930391Skarels 159030391Skarels /*------------------------------ 159130391Skarels * enable user write to DUART */ 159230391Skarels 159332012Smarc mapix = VTOP((int)qd->duart) - VTOP(qvmem[0]); 159432012Smarc ptep = (int *)(QVmap[0] + mapix); 159530391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ 159630391Skarels 159730391Skarels mtpr(TBIA, 0); /* smash CPU's translation buffer */ 159830391Skarels 159930391Skarels /*------------------------------------------ 160030391Skarels * stuff qdmap structure in return buffer */ 160130391Skarels 160230391Skarels bcopy(qd, datap, sizeof(struct qdmap)); 160330391Skarels break; 160430391Skarels 160530391Skarels /*------------------------------------- 160630391Skarels * do setup for DMA by user process */ 160730391Skarels 160830391Skarels case QD_MAPIOBUF: 160930391Skarels 161030391Skarels /*------------------------------------------------ 161130391Skarels * set 'user write enable' bits for DMA buffer */ 161230391Skarels 161330391Skarels qdflags[unit].mapped |= MAPDMA; 161430391Skarels 161530391Skarels ptep = (int *) ((VTOP(DMAheader[unit]) * 4) 161630391Skarels + (mfpr(SBR) | 0x80000000)); 161730391Skarels 161830391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 161930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 162030391Skarels 162130391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 162230391Skarels 162330391Skarels /*------------------------------------- 162430391Skarels * set up QBUS map registers for DMA */ 162530391Skarels 162630391Skarels DMAheader[unit]->QBAreg = 162730391Skarels uballoc(0, DMAheader[unit], DMAbuf_size, 0); 162830391Skarels 162930391Skarels if (DMAheader[unit]->QBAreg == 0) 1630*34615Smarc printf("\nqd%d: qdioctl: QBA setup error", unit); 163130391Skarels 163230391Skarels Qbus_unmap[unit] = DMAheader[unit]->QBAreg; 163330391Skarels DMAheader[unit]->QBAreg &= 0x3FFFF; 163430391Skarels 163530391Skarels /*---------------------- 163630391Skarels * return I/O buf adr */ 163730391Skarels 163830391Skarels *(int *)datap = (int) DMAheader[unit]; 163930391Skarels break; 164030391Skarels 164130391Skarels /*---------------------------------------------------------------- 164230391Skarels * map the shared scroll param area and enable scroll interpts */ 164330391Skarels 164430391Skarels case QD_MAPSCROLL: 164530391Skarels 164630391Skarels qdflags[unit].mapped |= MAPSCR; 164730391Skarels 164830391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 164930391Skarels + (mfpr(SBR) | 0x80000000)); 165030391Skarels 165130391Skarels /* allow user write to scroll area */ 165230391Skarels 165330391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 165430391Skarels 165530391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 165630391Skarels 165730391Skarels scroll[unit]->status = 0; 165830391Skarels 165930391Skarels adder = (struct adder *) qdmap[unit].adder; 166030391Skarels 166130391Skarels qdflags[unit].adder_ie |= FRAME_SYNC; 166230391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 166330391Skarels 1664*34615Smarc 166530391Skarels /* return scroll area address */ 166630391Skarels 166730391Skarels *(int *)datap = (int) scroll[unit]; 166830391Skarels break; 166930391Skarels 167030391Skarels /*------------------------------------------------------------- 167130391Skarels * unmap shared scroll param area and disable scroll intrpts */ 167230391Skarels 167330391Skarels case QD_UNMAPSCROLL: 167430391Skarels 167530391Skarels if (qdflags[unit].mapped & MAPSCR) { 167630391Skarels 167730391Skarels qdflags[unit].mapped &= ~MAPSCR; 167830391Skarels 167930391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 168030391Skarels + (mfpr(SBR) | 0x80000000)); 168130391Skarels 168230391Skarels /* re-protect 512 scroll param area */ 168330391Skarels 168430391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 168530391Skarels 168630391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 168730391Skarels 168830391Skarels adder = (struct adder *) qdmap[unit].adder; 168930391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 169030391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 169130391Skarels } 169230391Skarels break; 169330391Skarels 169430391Skarels /*----------------------------------------------------------- 169530391Skarels * map shared color map write buf and turn on vsync intrpt */ 169630391Skarels 169730391Skarels case QD_MAPCOLOR: 169830391Skarels 169930391Skarels qdflags[unit].mapped |= MAPCOLOR; 170030391Skarels 170130391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 170230391Skarels + (mfpr(SBR) | 0x80000000)); 170330391Skarels 170430391Skarels /* allow user write to color map write buffer */ 170530391Skarels 170630391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 170730391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 170830391Skarels 170930391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 1710*34615Smarc 1711*34615Smarc adder = (struct adder *) qdmap[unit].adder. 171230391Skarels qdflags[unit].adder_ie |= VSYNC; 171330391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 171430391Skarels 1715*34615Smarc /* return color area address */ 171630391Skarels 171730391Skarels *(int *)datap = (int) color_buf[unit]; 171830391Skarels break; 171930391Skarels 172030391Skarels /*-------------------------------------------------------------- 172130391Skarels * unmap shared color map write buffer and kill VSYNC intrpts */ 172230391Skarels 172330391Skarels case QD_UNMAPCOLOR: 172430391Skarels 172530391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 172630391Skarels 172730391Skarels qdflags[unit].mapped &= ~MAPCOLOR; 172830391Skarels 172930391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 173030391Skarels + (mfpr(SBR) | 0x80000000)); 173130391Skarels 173230391Skarels /* re-protect color map write buffer */ 173330391Skarels 173430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 173530391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 173630391Skarels 173730391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 173830391Skarels 173930391Skarels adder = (struct adder *) qdmap[unit].adder; 174030391Skarels 174130391Skarels qdflags[unit].adder_ie &= ~VSYNC; 174230391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 174330391Skarels } 174430391Skarels break; 174530391Skarels 174630391Skarels /*--------------------------------------------- 174730391Skarels * give user write access to the event queue */ 174830391Skarels 174930391Skarels case QD_MAPEVENT: 175030391Skarels 175130391Skarels qdflags[unit].mapped |= MAPEQ; 175230391Skarels 175330391Skarels ptep = (int *) ((VTOP(eq_header[unit]) * 4) 175430391Skarels + (mfpr(SBR) | 0x80000000)); 175530391Skarels 175630391Skarels /* allow user write to 1K event queue */ 175730391Skarels 175830391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 175930391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 176030391Skarels 176130391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 176230391Skarels 176330391Skarels /* return event queue address */ 176430391Skarels 176530391Skarels *(int *)datap = (int) eq_header[unit]; 176630391Skarels break; 176730391Skarels 176830391Skarels /*----------------------------------------------- 176930391Skarels * pass caller's programming commands to LK201 */ 177030391Skarels 177130391Skarels case QD_PRGKBD: 177230391Skarels 177330391Skarels duart = (struct duart *) qdmap[unit].duart; 177430391Skarels cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ 177530391Skarels 177630391Skarels /*---------------- 177730391Skarels * send command */ 177830391Skarels 177930391Skarels for (i = 1000; i > 0; --i) { 178030391Skarels if ((status = duart->statusA) & XMT_RDY) { 178130391Skarels duart->dataA = cmdbuf->cmd; 178230391Skarels break; 178330391Skarels } 178430391Skarels } 178530391Skarels 178630391Skarels if (i == 0) { 1787*34615Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [1]", unit); 178830391Skarels break; 178930391Skarels } 179030391Skarels 179130391Skarels /*---------------- 179230391Skarels * send param1? */ 179330391Skarels 179430391Skarels if (cmdbuf->cmd & LAST_PARAM) 179530391Skarels break; 179630391Skarels 179730391Skarels for (i = 1000; i > 0; --i) { 179830391Skarels if ((status = duart->statusA) & XMT_RDY) { 179930391Skarels duart->dataA = cmdbuf->param1; 180030391Skarels break; 180130391Skarels } 180230391Skarels } 180330391Skarels 180430391Skarels if (i == 0) { 1805*34615Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [2]", unit); 180630391Skarels break; 180730391Skarels } 180830391Skarels 180930391Skarels /*---------------- 181030391Skarels * send param2? */ 181130391Skarels 181230391Skarels if (cmdbuf->param1 & LAST_PARAM) 181330391Skarels break; 181430391Skarels 181530391Skarels for (i = 1000; i > 0; --i) { 181630391Skarels if ((status = duart->statusA) & XMT_RDY) { 181730391Skarels duart->dataA = cmdbuf->param2; 181830391Skarels break; 181930391Skarels } 182030391Skarels } 182130391Skarels 182230391Skarels if (i == 0) { 1823*34615Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [3]", unit); 182430391Skarels break; 182530391Skarels } 182630391Skarels 182730391Skarels break; 182830391Skarels 182930391Skarels /*---------------------------------------------------- 183030391Skarels * pass caller's programming commands to the mouse */ 183130391Skarels 183230391Skarels case QD_PRGMOUSE: 183330391Skarels 183430391Skarels duart = (struct duart *) qdmap[unit].duart; 183530391Skarels 183630391Skarels for (i = 1000; i > 0; --i) { 183730391Skarels if ((status = duart->statusB) & XMT_RDY) { 183830391Skarels duart->dataB = *datap; 183930391Skarels break; 184030391Skarels } 184130391Skarels } 184230391Skarels 184330391Skarels if (i == 0) { 1844*34615Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [4]", unit); 184530391Skarels } 184630391Skarels 184730391Skarels break; 184830391Skarels 184930391Skarels /*---------------------------------------------- 185030391Skarels * get QDSS configuration word and return it */ 185130391Skarels 185230391Skarels case QD_RDCONFIG: 185330391Skarels 185430391Skarels *(short *)datap = qdflags[unit].config; 185530391Skarels break; 185630391Skarels 1857*34615Smarc /*-------------------------------------------------------------- 1858*34615Smarc * re-route kernel console messages to the alternate console */ 1859*34615Smarc 1860*34615Smarc case QD_KERN_LOOP: 1861*34615Smarc 1862*34615Smarc qdflags[unit].kernel_loop = -1; 1863*34615Smarc break; 1864*34615Smarc 1865*34615Smarc case QD_KERN_UNLOOP: 1866*34615Smarc 1867*34615Smarc qdflags[unit].kernel_loop = 0; 1868*34615Smarc break; 1869*34615Smarc 187030391Skarels /*---------------------- 187130391Skarels * program the tablet */ 187230391Skarels 187330391Skarels case QD_PRGTABLET: 187430391Skarels 187530391Skarels duart = (struct duart *) qdmap[unit].duart; 187630391Skarels 187730391Skarels for (i = 1000; i > 0; --i) { 187830391Skarels if ((status = duart->statusB) & XMT_RDY) { 187930391Skarels duart->dataB = *datap; 188030391Skarels break; 188130391Skarels } 188230391Skarels } 188330391Skarels 188430391Skarels if (i == 0) { 1885*34615Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [5]", unit); 188630391Skarels } 188730391Skarels 188830391Skarels break; 188930391Skarels 189030391Skarels /*----------------------------------------------- 189130391Skarels * program the tablet report resolution factor */ 189230391Skarels 189330391Skarels case QD_PRGTABRES: 189430391Skarels 189530391Skarels qdflags[unit].tab_res = *(short *)datap; 189630391Skarels break; 1897*34615Smarc #ifdef notdef /* never */ 1898*34615Smarc case DEVIOCGET: /* device status */ 1899*34615Smarc devget = (struct devget *)datap; 1900*34615Smarc bzero(devget,sizeof(struct devget)); 1901*34615Smarc devget->category = DEV_TERMINAL; 1902*34615Smarc devget->bus = DEV_QB; 1903*34615Smarc bcopy(DEV_VCB02,devget->interface, 1904*34615Smarc strlen(DEV_VCB02)); 1905*34615Smarc bcopy(DEV_VR290,devget->device, 1906*34615Smarc strlen(DEV_VR290)); /* terminal */ 1907*34615Smarc devget->adpt_num = ui->ui_adpt; /* which adapter*/ 1908*34615Smarc devget->nexus_num = ui->ui_nexus; /* which nexus */ 1909*34615Smarc devget->bus_num = ui->ui_ubanum; /* which QB */ 1910*34615Smarc devget->ctlr_num = unit; /* which interf.*/ 1911*34615Smarc devget->slave_num = unit; /* which line */ 1912*34615Smarc bcopy(ui->ui_driver->ud_dname, 1913*34615Smarc devget->dev_name, 1914*34615Smarc strlen(ui->ui_driver->ud_dname)); /* Ultrix "qd" */ 1915*34615Smarc devget->unit_num = unit; /* qd line? */ 1916*34615Smarc devget->soft_count = 1917*34615Smarc sc->sc_softcnt; /* soft er. cnt.*/ 1918*34615Smarc devget->hard_count = 1919*34615Smarc sc->sc_hardcnt; /* hard er cnt. */ 1920*34615Smarc devget->stat = sc->sc_flags; /* status */ 1921*34615Smarc devget->category_stat = 1922*34615Smarc sc->sc_category_flags; /* cat. stat. */ 1923*34615Smarc break; 1924*34615Smarc #endif /*notdef*/ 192530391Skarels 192630391Skarels default: 192730391Skarels /*----------------------------- 192830391Skarels * service tty type ioctl's */ 192930391Skarels 193030391Skarels if (!(minor_dev & 0x02)) { 193130391Skarels 193230391Skarels tp = &qd_tty[minor_dev]; 193330391Skarels 193430391Skarels error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); 193530391Skarels if (error >= 0) { 193630391Skarels return(error); 193730391Skarels } 193830391Skarels 193930391Skarels error = ttioctl(tp, cmd, datap, flags); 194030391Skarels if (error >= 0) { 194130391Skarels return(error); 194230391Skarels } 194330391Skarels } 194430391Skarels break; 194530391Skarels } 194630391Skarels 194730391Skarels /*-------------------------------- 194830391Skarels * clean up and get outta here */ 194930391Skarels 195030391Skarels return(0); 195130391Skarels 195230391Skarels } /* qdioctl */ 195330391Skarels 195430391Skarels /********************************************************************** 195530391Skarels * 195630391Skarels * qdselect()... service select call for event queue input 195730391Skarels * 195830391Skarels **********************************************************************/ 195930391Skarels 196030391Skarels qdselect(dev, rw) 196130391Skarels dev_t dev; 196230391Skarels int rw; 196330391Skarels { 196430391Skarels register int s; 196530391Skarels register int unit; 1966*34615Smarc register struct tty *tp; 1967*34615Smarc u_int minor_dev = minor(dev); 196830391Skarels 1969*34615Smarc s = spl5(); 1970*34615Smarc unit = minor_dev >> 2; 197130391Skarels 197230391Skarels switch (rw) { 197330391Skarels 1974*34615Smarc case FREAD: 197530391Skarels 1976*34615Smarc if ((minor_dev & 0x03) == 2) 1977*34615Smarc { 1978*34615Smarc /* 1979*34615Smarc * this is a graphics device, so check for events 1980*34615Smarc */ 1981*34615Smarc if(!(ISEMPTY(eq_header[unit]))) 1982*34615Smarc { 1983*34615Smarc splx(s); 1984*34615Smarc return(1); 1985*34615Smarc } 1986*34615Smarc rsel[unit] = u.u_procp; 1987*34615Smarc qdflags[unit].selmask |= SEL_READ; 198830391Skarels splx(s); 1989*34615Smarc return(0); 199030391Skarels } 1991*34615Smarc else 1992*34615Smarc { 1993*34615Smarc /* 1994*34615Smarc * this is a tty device 1995*34615Smarc */ 1996*34615Smarc tp = &qd_tty[minor_dev]; 1997*34615Smarc if (ttnread(tp)) 1998*34615Smarc return(1); 1999*34615Smarc tp->t_rsel = u.u_procp; 2000*34615Smarc splx(s); 2001*34615Smarc return(0); 2002*34615Smarc } 200330391Skarels 2004*34615Smarc case FWRITE: 200530391Skarels 2006*34615Smarc if ((minor(dev) & 0x03) == 2) 2007*34615Smarc { 2008*34615Smarc /* 2009*34615Smarc * this is a graphics device, so check for dma buffers 2010*34615Smarc */ 2011*34615Smarc if (DMA_ISEMPTY(DMAheader[unit])) 2012*34615Smarc { 2013*34615Smarc splx(s); 2014*34615Smarc return(1); 2015*34615Smarc } 2016*34615Smarc rsel[unit] = u.u_procp; 2017*34615Smarc qdflags[unit].selmask |= SEL_WRITE; 201830391Skarels splx(s); 2019*34615Smarc return(0); 202030391Skarels } 2021*34615Smarc else 2022*34615Smarc { 2023*34615Smarc /* 2024*34615Smarc * this is a tty device 2025*34615Smarc */ 2026*34615Smarc tp = &qd_tty[minor_dev]; 2027*34615Smarc if (tp->t_outq.c_cc <= TTLOWAT(tp)) 2028*34615Smarc return(1); 2029*34615Smarc tp->t_wsel = u.u_procp; 2030*34615Smarc splx(s); 2031*34615Smarc return(0); 2032*34615Smarc } 203330391Skarels } 203430391Skarels 203530391Skarels } /* qdselect() */ 203630391Skarels 203730391Skarels /*************************************************************** 203830391Skarels * 203930391Skarels * qdwrite()... output to the QDSS screen as a TTY 204030391Skarels * 204130391Skarels ***************************************************************/ 204230391Skarels 204330391Skarels extern qd_strategy(); 204430391Skarels 204530391Skarels qdwrite(dev, uio) 204630391Skarels dev_t dev; 204730391Skarels struct uio *uio; 204830391Skarels { 204930391Skarels register struct tty *tp; 205030391Skarels register int minor_dev; 205130391Skarels register int unit; 205230391Skarels 205330391Skarels minor_dev = minor(dev); 205430391Skarels unit = (minor_dev >> 2) & 0x07; 205530391Skarels 205630391Skarels /*------------------------------ 205730391Skarels * if this is the console... */ 205830391Skarels 205930391Skarels if ((minor_dev & 0x03) != 0x02 && 206030391Skarels qdflags[unit].inuse & CONS_DEV) { 206130391Skarels tp = &qd_tty[minor_dev]; 206230391Skarels return ((*linesw[tp->t_line].l_write)(tp, uio)); 206330391Skarels } 206430391Skarels 206530391Skarels /*------------------------------------------------ 206630391Skarels * else this must be a DMA xfer from user space */ 206730391Skarels 206830391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 206930391Skarels return (physio(qd_strategy, &qdbuf[unit], 207030391Skarels dev, B_WRITE, minphys, uio)); 207130391Skarels } 207230391Skarels } 207330391Skarels 207430391Skarels /*************************************************************** 207530391Skarels * 207630391Skarels * qdread()... read from QDSS keyboard as a TTY 207730391Skarels * 207830391Skarels ***************************************************************/ 207930391Skarels 208030391Skarels qdread(dev, uio) 208130391Skarels dev_t dev; 208230391Skarels struct uio *uio; 208330391Skarels { 208430391Skarels register struct tty *tp; 208530391Skarels register int minor_dev; 208630391Skarels register int unit; 208730391Skarels 208830391Skarels minor_dev = minor(dev); 208930391Skarels unit = (minor_dev >> 2) & 0x07; 209030391Skarels 209130391Skarels /*------------------------------ 209230391Skarels * if this is the console... */ 209330391Skarels 209430391Skarels if ((minor_dev & 0x03) != 0x02 && 209530391Skarels qdflags[unit].inuse & CONS_DEV) { 209630391Skarels tp = &qd_tty[minor_dev]; 209730391Skarels return ((*linesw[tp->t_line].l_read)(tp, uio)); 209830391Skarels } 209930391Skarels 210030391Skarels /*------------------------------------------------ 210130391Skarels * else this must be a bitmap-to-processor xfer */ 210230391Skarels 210330391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 210430391Skarels return (physio(qd_strategy, &qdbuf[unit], 210530391Skarels dev, B_READ, minphys, uio)); 210630391Skarels } 210730391Skarels } 210830391Skarels 210930391Skarels /*************************************************************** 211030391Skarels * 211130391Skarels * qd_strategy()... strategy routine to do DMA 211230391Skarels * 211330391Skarels ***************************************************************/ 211430391Skarels 211530391Skarels qd_strategy(bp) 211630391Skarels register struct buf *bp; 211730391Skarels { 211830391Skarels register struct dga *dga; 211930391Skarels register struct adder *adder; 212030391Skarels 212130391Skarels char *DMAbufp; 212230391Skarels 212330391Skarels int QBAreg; 212430391Skarels int bytcnt; 212530391Skarels int s; 212630391Skarels int unit; 212730391Skarels int cookie; 212830391Skarels 212930391Skarels int i,j,k; 213030391Skarels 213130391Skarels unit = (minor(bp->b_dev) >> 2) & 0x07; 213230391Skarels 2133*34615Smarc /*----------------- 2134*34615Smarc * init pointers */ 213530391Skarels 213630391Skarels if ((QBAreg = ubasetup(0, bp, 0)) == 0) { 2137*34615Smarc printf("\nqd%d: qd_strategy: QBA setup error", unit); 213830391Skarels goto STRAT_ERR; 213930391Skarels } 214030391Skarels 214130391Skarels dga = (struct dga *) qdmap[unit].dga; 214230391Skarels 2143*34615Smarc s = spl5(); 214430391Skarels 214530391Skarels qdflags[unit].user_dma = -1; 214630391Skarels 214730391Skarels dga->csr |= DMA_IE; 214830391Skarels 214930391Skarels cookie = QBAreg & 0x3FFFF; 215030391Skarels dga->adrs_lo = (short) cookie; 215130391Skarels dga->adrs_hi = (short) (cookie >> 16); 215230391Skarels 215330391Skarels dga->bytcnt_lo = (short) bp->b_bcount; 215430391Skarels dga->bytcnt_hi = (short) (bp->b_bcount >> 16); 215530391Skarels 215630391Skarels while (qdflags[unit].user_dma) { 215730391Skarels sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); 215830391Skarels } 215930391Skarels 216030391Skarels splx(s); 216130391Skarels ubarelse(0, &QBAreg); 216230391Skarels 216330391Skarels if (!(dga->csr & DMA_ERR)) { 216430391Skarels iodone(bp); 216530391Skarels return; 216630391Skarels } 216730391Skarels 216830391Skarels STRAT_ERR: 216930391Skarels adder = (struct adder *) qdmap[unit].adder; 217030391Skarels adder->command = CANCEL; /* cancel adder activity */ 217130391Skarels dga->csr &= ~DMA_IE; 217230391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 217330391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 217430391Skarels bp->b_flags |= B_ERROR; /* flag an error to physio() */ 217530391Skarels 217630391Skarels /* if DMA was running, flush spurious intrpt */ 217730391Skarels 217830391Skarels if (dga->bytcnt_lo != 0) { 217930391Skarels dga->bytcnt_lo = 0; 218030391Skarels dga->bytcnt_hi = 0; 218130391Skarels DMA_SETIGNORE(DMAheader[unit]); 218230391Skarels dga->csr |= DMA_IE; 218330391Skarels } 218430391Skarels 218530391Skarels iodone(bp); 218630391Skarels 218730391Skarels } /* qd_strategy */ 218830391Skarels 218930391Skarels /******************************************************************* 219030391Skarels * 219130391Skarels * qdstart()... startup output to the console screen 219230391Skarels * 219330391Skarels ******************************************************************** 219430391Skarels * 219530391Skarels * calling convention: 219630391Skarels * 219730391Skarels * qdstart(tp); 2198*34615Smarc * struct tty *tp; ;pointer to tty structure 219930391Skarels * 220030391Skarels ********/ 220130391Skarels 220230391Skarels qdstart(tp) 220330391Skarels register struct tty *tp; 220430391Skarels { 220530391Skarels register int which_unit, unit, c; 2206*34615Smarc register struct tty *tp0; 220730391Skarels int s; 220830391Skarels 2209*34615Smarc int curs_on; 2210*34615Smarc struct dga *dga; 2211*34615Smarc 221230391Skarels unit = minor(tp->t_dev); 2213*34615Smarc 2214*34615Smarc tp0 = &qd_tty[(unit & 0x0FC)+1]; 221530391Skarels which_unit = (unit >> 2) & 0x3; 2216*34615Smarc unit &= 0x03; 221730391Skarels 2218*34615Smarc s = spl5(); 2219*34615Smarc 2220*34615Smarc /*------------------------------------------------------------------ 2221*34615Smarc * If it's currently active, or delaying, no need to do anything. */ 2222*34615Smarc 222330391Skarels if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 222430391Skarels goto out; 222530391Skarels 2226*34615Smarc /*------------------------------------------------------------------- 2227*34615Smarc * Display chars until the queue is empty, if the alternate console device 2228*34615Smarc * is open direct chars there. Drop input from anything but the console 2229*34615Smarc * device on the floor. */ 2230*34615Smarc /* TANDEM is set on the second subchannel for flow control. */ 2231*34615Smarc 2232*34615Smarc while ( tp->t_outq.c_cc ) { 223334511Smarc c = getc(&tp->t_outq); 2234*34615Smarc if (unit == 0) 2235*34615Smarc blitc(which_unit, (char)(c & 0xFF)); 2236*34615Smarc #ifdef notdef /* never never never */ 2237*34615Smarc if (unit == 0) { /* console device */ 2238*34615Smarc if (tp0->t_state & TS_ISOPEN) { 2239*34615Smarc if (tp0->t_state & TS_TBLOCK) 2240*34615Smarc goto out; 2241*34615Smarc c = getc(&tp->t_outq); 2242*34615Smarc (*linesw[tp0->t_line].l_rint)(c, tp0); 2243*34615Smarc } else { 2244*34615Smarc c = getc(&tp->t_outq); 2245*34615Smarc blitc(which_unit, (char)(c & 0xFF)); 2246*34615Smarc } 2247*34615Smarc } else if (unit == 1) { /* qconsole, do flow control */ 2248*34615Smarc c = getc(&tp->t_outq); 2249*34615Smarc if ((tp0->t_state&TS_TBLOCK) == 0) { 2250*34615Smarc tp = &qd_tty[0]; 2251*34615Smarc unit = minor(tp->t_dev); 2252*34615Smarc unit &= 0x03; 2253*34615Smarc continue; 2254*34615Smarc } else 2255*34615Smarc goto out; 2256*34615Smarc } else 2257*34615Smarc c = getc(&tp->t_outq); 2258*34615Smarc #endif 225930391Skarels } 2260*34615Smarc 2261*34615Smarc /*-------------------------------------------------------- 2262*34615Smarc * If there are sleepers, and output has drained below low 2263*34615Smarc * water mark, wake up the sleepers. */ 2264*34615Smarc 2265*34615Smarc if ( tp->t_outq.c_cc <= TTLOWAT(tp) ) { 2266*34615Smarc if (tp->t_state & TS_ASLEEP){ 2267*34615Smarc tp->t_state &= ~TS_ASLEEP; 2268*34615Smarc wakeup((caddr_t) &tp->t_outq); 2269*34615Smarc } 227030391Skarels } 227130391Skarels 2272*34615Smarc tp->t_state &= ~TS_BUSY; 2273*34615Smarc 227430391Skarels out: 227530391Skarels splx(s); 227630391Skarels 227730391Skarels } /* qdstart */ 227830391Skarels 227930391Skarels 228030391Skarels /******************************************************************* 228130391Skarels * 228230391Skarels * qdstop()... stop the tty 228330391Skarels * 228430391Skarels *******************************************************************/ 228530391Skarels 228630391Skarels qdstop(tp, flag) 228730391Skarels register struct tty *tp; 228830391Skarels int flag; 228930391Skarels { 229030391Skarels register int s; 229130391Skarels 2292*34615Smarc s = spl5(); /* block intrpts during state modification */ 2293*34615Smarc 229430391Skarels if (tp->t_state & TS_BUSY) { 229530391Skarels if ((tp->t_state & TS_TTSTOP) == 0) { 229630391Skarels tp->t_state |= TS_FLUSH; 229730391Skarels } else 229830391Skarels tp->t_state &= ~TS_BUSY; 229930391Skarels } 230030391Skarels splx(s); 230130391Skarels } 230230391Skarels 230330391Skarels /******************************************************************* 230430391Skarels * 230530391Skarels * blitc()... output a character to the QDSS screen 230630391Skarels * 230730391Skarels ******************************************************************** 230830391Skarels * 230930391Skarels * calling convention: 231030391Skarels * 231130391Skarels * blitc(chr); 231230391Skarels * char chr; ;character to be displayed 231330391Skarels * 231430391Skarels ********/ 231530391Skarels 231630391Skarels blitc(unit, chr) 231730391Skarels int unit; 2318*34615Smarc unsigned char chr; 231930391Skarels { 232030391Skarels register struct adder *adder; 232130391Skarels register struct dga *dga; 232230391Skarels register int i; 232330391Skarels 232430391Skarels short x; 2325*34615Smarc unsigned char savechar; 232630391Skarels 2327*34615Smarc /*--------------- 2328*34615Smarc * init stuff */ 232930391Skarels 233030391Skarels adder = (struct adder *) qdmap[unit].adder; 233130391Skarels dga = (struct dga *) qdmap[unit].dga; 233230391Skarels 2333*34615Smarc /*--------------------------- 2334*34615Smarc * non display character? */ 233530391Skarels 2336*34615Smarc chr &= 0xFF; 233732012Smarc 233830391Skarels switch (chr) { 233930391Skarels 234030391Skarels case '\r': /* return char */ 234130391Skarels cursor[unit].x = 0; 2342*34615Smarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 2343*34615Smarc dga->x_cursor = TRANX(cursor[unit].x); 234430391Skarels return(0); 234530391Skarels 234630391Skarels case '\t': /* tab char */ 234730391Skarels 234830391Skarels for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) { 234930391Skarels blitc(unit, ' '); 235030391Skarels } 235130391Skarels return(0); 235230391Skarels 235330391Skarels case '\n': /* line feed char */ 235430391Skarels 235530391Skarels if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { 235630391Skarels if (qdflags[unit].inuse & GRAPHIC_DEV) { 235730391Skarels cursor[unit].y = 0; 235830391Skarels } else { 235930391Skarels cursor[unit].y -= CHAR_HEIGHT; 236030391Skarels scroll_up(adder); 236130391Skarels } 236230391Skarels } 2363*34615Smarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 2364*34615Smarc dga->y_cursor = TRANY(cursor[unit].y); 236530391Skarels return(0); 236630391Skarels 236730391Skarels case '\b': /* backspace char */ 236830391Skarels if (cursor[unit].x > 0) { 236930391Skarels cursor[unit].x -= CHAR_WIDTH; 2370*34615Smarc blitc(unit, ' '); 2371*34615Smarc cursor[unit].x -= CHAR_WIDTH; 2372*34615Smarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 2373*34615Smarc dga->x_cursor = TRANX(cursor[unit].x); 237430391Skarels } 237530391Skarels return(0); 237630391Skarels 2377*34615Smarc default: 2378*34615Smarc /*---------------------------------------------------------- 2379*34615Smarc * Weed out unprintable characters. Printable characters fall 2380*34615Smarc * between space (0x20) and tilde (0x7E). For 8-bit support 2381*34615Smarc * another range of printable characters are those between 2382*34615Smarc * 0xA1 and 0xFD. */ 238332012Smarc 2384*34615Smarc if ((chr < ' ') || (chr > 0xFD) || (chr < 0xA1 && chr > '~')) 238530391Skarels return(0); 238630391Skarels } 238730391Skarels 2388*34615Smarc /*------------------------------------------ 2389*34615Smarc * setup VIPER operand control registers */ 239030391Skarels 239130391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ 239230391Skarels write_ID(adder, SRC1_OCR_B, 239330391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 239430391Skarels 239530391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ 239630391Skarels write_ID(adder, SRC1_OCR_B, 239730391Skarels EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); 239830391Skarels 239930391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 240030391Skarels write_ID(adder, DST_OCR_B, 240130391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 240230391Skarels 240330391Skarels write_ID(adder, MASK_1, 0xFFFF); 240430391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); 240530391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 240630391Skarels 2407*34615Smarc adder->x_clip_min = 0; 2408*34615Smarc adder->x_clip_max = 1024; 2409*34615Smarc adder->y_clip_min = 0; 2410*34615Smarc adder->y_clip_max = 864; 241130391Skarels 2412*34615Smarc /*---------------------------------------- 2413*34615Smarc * load DESTINATION origin and vectors */ 2414*34615Smarc 241530391Skarels adder->fast_dest_dy = 0; 241630391Skarels adder->slow_dest_dx = 0; 241730391Skarels adder->error_1 = 0; 241830391Skarels adder->error_2 = 0; 241930391Skarels 242030391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 242130391Skarels 242230391Skarels wait_status(adder, RASTEROP_COMPLETE); 242330391Skarels 242430391Skarels adder->destination_x = cursor[unit].x; 242530391Skarels adder->fast_dest_dx = CHAR_WIDTH; 242630391Skarels 242730391Skarels adder->destination_y = cursor[unit].y; 242830391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 242930391Skarels 2430*34615Smarc /*----------------------------------- 2431*34615Smarc * load SOURCE origin and vectors */ 243230391Skarels 2433*34615Smarc if (chr > '~') { 2434*34615Smarc savechar = chr; 2435*34615Smarc chr -= 34; /* These are to skip the (32) 8-bit control chars. 2436*34615Smarc as well as DEL and 0xA0 which aren't printable */ 2437*34615Smarc } 2438*34615Smarc if ((chr - ' ') > (CHARS - 1)) { 2439*34615Smarc printf("Invalid character (x)%x in blitc\n",chr); 2440*34615Smarc chr = ' '; 2441*34615Smarc } 2442*34615Smarc /* X position is modulo the number of characters per line */ 2443*34615Smarc adder->source_1_x = FONT_X + 2444*34615Smarc (((chr - ' ') % (MAX_SCREEN_X/CHAR_WIDTH)) * CHAR_WIDTH); 2445*34615Smarc /* Point to either first or second row */ 2446*34615Smarc adder->source_1_y = 2048 - 15 * 2447*34615Smarc (((chr - ' ')/(MAX_SCREEN_X/CHAR_WIDTH)) + 1); 244830391Skarels 244930391Skarels adder->source_1_dx = CHAR_WIDTH; 245030391Skarels adder->source_1_dy = CHAR_HEIGHT; 245130391Skarels 245230391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 245330391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 245430391Skarels 2455*34615Smarc /*------------------------------------- 2456*34615Smarc * update console cursor coordinates */ 245730391Skarels 245830391Skarels cursor[unit].x += CHAR_WIDTH; 2459*34615Smarc if (!(qdflags[unit].inuse & GRAPHIC_DEV)) 2460*34615Smarc dga->x_cursor = TRANX(cursor[unit].x); 246130391Skarels 246230391Skarels if (cursor[unit].x > (1024 - CHAR_WIDTH)) { 246330391Skarels blitc(unit, '\r'); 246430391Skarels blitc(unit, '\n'); 246530391Skarels } 246630391Skarels 246730391Skarels } /* blitc */ 246830391Skarels 246930391Skarels qdreset(){} 247030391Skarels qd_init(){} 247130391Skarels 247230391Skarels /****************************************************************** 2473*34615Smarc ******************************************************************* 2474*34615Smarc ******************************************************************* 247530391Skarels * 247630391Skarels * INTERRUPT SERVICE ROUTINES START HERE: 247730391Skarels * 2478*34615Smarc ******************************************************************* 2479*34615Smarc ******************************************************************* 248030391Skarels ******************************************************************/ 248130391Skarels 248230391Skarels /***************************************************************** 248330391Skarels * 248430391Skarels * qddint()... service "DMA DONE" interrupt condition 248530391Skarels * 248630391Skarels *****************************************************************/ 248730391Skarels 248830391Skarels qddint(qd) 248930391Skarels int qd; 249030391Skarels { 249130391Skarels register struct DMAreq_header *header; 249230391Skarels register struct DMAreq *request; 249330391Skarels register struct dga *dga; 249430391Skarels struct adder *adder; 249530391Skarels 249630391Skarels int cookie; /* DMA adrs for QDSS */ 249730391Skarels int i; 249830391Skarels 249930391Skarels spl4(); /* allow interval timer in */ 250030391Skarels 2501*34615Smarc /*----------------- 2502*34615Smarc * init pointers */ 250330391Skarels 250430391Skarels header = DMAheader[qd]; /* register for optimization */ 250530391Skarels dga = (struct dga *) qdmap[qd].dga; 250630391Skarels adder = (struct adder *) qdmap[qd].adder; 250730391Skarels 2508*34615Smarc /*------------------------------------------------------------------------ 2509*34615Smarc * if this interrupt flagged as bogus for interrupt flushing purposes.. */ 251030391Skarels 251130391Skarels if (DMA_ISIGNORE(header)) { 251230391Skarels DMA_CLRIGNORE(header); 251330391Skarels return; 251430391Skarels } 251530391Skarels 251630391Skarels /*---------------------------------------------------- 251730391Skarels * dump a DMA hardware error message if appropriate */ 251830391Skarels 251930391Skarels if (dga->csr & DMA_ERR) { 252030391Skarels 252130391Skarels if (dga->csr & PARITY_ERR) 2522*34615Smarc printf("\nqd%d: qddint: DMA hardware parity fault.", qd); 252330391Skarels 252430391Skarels if (dga->csr & BUS_ERR) 2525*34615Smarc printf("\nqd%d: qddint: DMA hardware bus error.", qd); 252630391Skarels } 252730391Skarels 252830391Skarels /*---------------------------------------- 252930391Skarels * if this was a DMA from user space... */ 253030391Skarels 253130391Skarels if (qdflags[qd].user_dma) { 253230391Skarels qdflags[qd].user_dma = 0; 253330391Skarels wakeup((caddr_t)&qdflags[qd].user_dma); 253430391Skarels return; 253530391Skarels } 253630391Skarels 253730391Skarels /*------------------------------------------------------------------------ 253830391Skarels * if we're doing DMA request queue services, field the error condition */ 253930391Skarels 254030391Skarels if (dga->csr & DMA_ERR) { 254130391Skarels 254230391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 254330391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 254430391Skarels adder->command = CANCEL; /* cancel adder activity */ 254530391Skarels 254630391Skarels DMA_SETERROR(header); /* flag error in header status word */ 254730391Skarels DMA_CLRACTIVE(header); 254830391Skarels header->DMAreq[header->oldest].DMAdone |= HARD_ERROR; 254930391Skarels header->newest = header->oldest; 255030391Skarels header->used = 0; 255130391Skarels 255230391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 255330391Skarels selwakeup(rsel[qd], 0); 255430391Skarels rsel[qd] = 0; 255530391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 255630391Skarels } 255730391Skarels 255830391Skarels if (dga->bytcnt_lo != 0) { 255930391Skarels dga->bytcnt_lo = 0; 256030391Skarels dga->bytcnt_hi = 0; 256130391Skarels DMA_SETIGNORE(header); 256230391Skarels } 256330391Skarels 256430391Skarels return; 256530391Skarels } 256630391Skarels 256730391Skarels /*---------------------------------------------------------------------------- 256830391Skarels * if the DMA request queue is now becoming non-full, wakeup "select" client */ 256930391Skarels 257030391Skarels if (DMA_ISFULL(header)) { 257130391Skarels 257230391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 257330391Skarels selwakeup(rsel[qd], 0); 257430391Skarels rsel[qd] = 0; 257530391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 257630391Skarels } 257730391Skarels } 257830391Skarels 257930391Skarels header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE; 2580*34615Smarc QDlast_DMAtype = header->DMAreq[header->oldest].DMAtype; 258130391Skarels 2582*34615Smarc /* check for unexpected interrupt */ 2583*34615Smarc if (DMA_ISEMPTY(header)) 258430391Skarels return; 258530391Skarels 258630391Skarels DMA_GETEND(header); /* update request queue indices */ 258730391Skarels 258830391Skarels /*------------------------------------------------------------ 258930391Skarels * if no more DMA pending, wake up "select" client and exit */ 259030391Skarels 259130391Skarels if (DMA_ISEMPTY(header)) { 259230391Skarels 259330391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 259430391Skarels selwakeup(rsel[qd], 0); 259530391Skarels rsel[qd] = 0; 259630391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 259730391Skarels } 259830391Skarels 259930391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 260030391Skarels return; 260130391Skarels } 260230391Skarels 260330391Skarels /*--------------------------- 260430391Skarels * initiate next DMA xfer */ 260530391Skarels 260630391Skarels request = DMA_GETBEGIN(header); 2607*34615Smarc if (request->DMAtype != QDlast_DMAtype) { 2608*34615Smarc dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 2609*34615Smarc adder->command = CANCEL; /* cancel adder activity */ 2610*34615Smarc } 261130391Skarels 2612*34615Smarc 261330391Skarels switch (request->DMAtype) { 261430391Skarels 261530391Skarels case DISPLIST: 2616*34615Smarc if (request->DMAtype != QDlast_DMAtype) { 2617*34615Smarc dga->csr |= DL_ENB; 2618*34615Smarc dga->csr &= ~(BTOP_ENB | BYTE_DMA); 2619*34615Smarc } 262030391Skarels break; 262130391Skarels 262230391Skarels case PTOB: 2623*34615Smarc if (request->DMAtype != QDlast_DMAtype) { 2624*34615Smarc if (request->DMAdone & BYTE_PACK) 2625*34615Smarc dga->csr |= (PTOB_ENB | BYTE_DMA); 2626*34615Smarc else { 2627*34615Smarc dga->csr |= PTOB_ENB; 2628*34615Smarc dga->csr &= ~BYTE_DMA; 2629*34615Smarc } 2630*34615Smarc } 263130391Skarels break; 263230391Skarels 263330391Skarels case BTOP: 2634*34615Smarc if (request->DMAtype != QDlast_DMAtype) { 2635*34615Smarc if (request->DMAdone & BYTE_PACK) { 2636*34615Smarc dga->csr &= ~DL_ENB; 2637*34615Smarc dga->csr |= (BTOP_ENB | BYTE_DMA); 2638*34615Smarc } 2639*34615Smarc else { 2640*34615Smarc dga->csr |= BTOP_ENB; 2641*34615Smarc dga->csr &= ~(BYTE_DMA | DL_ENB); 2642*34615Smarc } 2643*34615Smarc } 264430391Skarels break; 264530391Skarels default: 2646*34615Smarc printf("\nqd%d: qddint: illegal DMAtype parameter.", qd); 264730391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 264830391Skarels return; 264930391Skarels } 265030391Skarels 265130391Skarels if (request->DMAdone & COUNT_ZERO) { 265230391Skarels dga->csr &= ~SET_DONE_FIFO; 265330391Skarels } else if (request->DMAdone & FIFO_EMPTY) { 265430391Skarels dga->csr |= SET_DONE_FIFO; 265530391Skarels } 265630391Skarels 265730391Skarels if (request->DMAdone & WORD_PACK) 265830391Skarels dga->csr &= ~BYTE_DMA; 265930391Skarels else if (request->DMAdone & BYTE_PACK) 266030391Skarels dga->csr |= BYTE_DMA; 266130391Skarels 266230391Skarels dga->csr |= DMA_IE; 2663*34615Smarc QDlast_DMAtype = request->DMAtype; 266430391Skarels 266530391Skarels cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg; 266630391Skarels 266730391Skarels dga->adrs_lo = (short) cookie; 266830391Skarels dga->adrs_hi = (short) (cookie >> 16); 266930391Skarels 267030391Skarels dga->bytcnt_lo = (short) request->length; 267130391Skarels dga->bytcnt_hi = (short) (request->length >> 16); 267230391Skarels 267330391Skarels return; 267430391Skarels } 267530391Skarels 267630391Skarels /***************************************************************** 267730391Skarels * 267830391Skarels * qdaint()... ADDER interrupt service 267930391Skarels * 268030391Skarels *****************************************************************/ 2681*34615Smarc int Nqdaint; 268230391Skarels 268330391Skarels qdaint(qd) 268430391Skarels register int qd; 268530391Skarels { 268630391Skarels register struct adder *adder; 268730391Skarels struct color_buf *cbuf; 268830391Skarels 268930391Skarels short stat; 269030391Skarels int i; 269130391Skarels register struct rgb *rgbp; 269230391Skarels register short *red; 269330391Skarels register short *green; 269430391Skarels register short *blue; 269530391Skarels 269630391Skarels spl4(); /* allow interval timer in */ 2697*34615Smarc Nqdaint++; /* debug */ 269830391Skarels 269930391Skarels adder = (struct adder *) qdmap[qd].adder; 270030391Skarels 270130391Skarels /*------------------------------------------------------------------------ 270230391Skarels * service the vertical blank interrupt (VSYNC bit) by loading any pending 270330391Skarels * color map load request */ 270430391Skarels 270530391Skarels if (adder->status & VSYNC) { 270630391Skarels adder->status &= ~VSYNC; /* clear the interrupt */ 270730391Skarels 270830391Skarels cbuf = color_buf[qd]; 270930391Skarels if (cbuf->status & LOAD_COLOR_MAP) { 271030391Skarels 271130391Skarels red = (short *) qdmap[qd].red; 271230391Skarels green = (short *) qdmap[qd].green; 271330391Skarels blue = (short *) qdmap[qd].blue; 271430391Skarels 271530391Skarels for (i = cbuf->count, rgbp = cbuf->rgb; --i >= 0; rgbp++) { 271630391Skarels 271730391Skarels red[rgbp->offset] = (short) rgbp->red; 271830391Skarels green[rgbp->offset] = (short) rgbp->green; 271930391Skarels blue[rgbp->offset] = (short) rgbp->blue; 272030391Skarels } 272130391Skarels 272230391Skarels cbuf->status &= ~LOAD_COLOR_MAP; 272330391Skarels } 272430391Skarels } 272530391Skarels 272630391Skarels /*------------------------------------------------- 272730391Skarels * service the scroll interrupt (FRAME_SYNC bit) */ 272830391Skarels 272930391Skarels if (adder->status & FRAME_SYNC) { 273030391Skarels adder->status &= ~FRAME_SYNC; /* clear the interrupt */ 273130391Skarels 273230391Skarels if (scroll[qd]->status & LOAD_REGS) { 273330391Skarels 273430391Skarels for ( i = 1000, adder->status = 0 273530391Skarels ; i > 0 && !((stat = adder->status) & ID_SCROLL_READY) 273630391Skarels ; --i); 273730391Skarels 273830391Skarels if (i == 0) { 2739*34615Smarc printf("\nqd%d: qdaint: timeout on ID_SCROLL_READY", qd); 274030391Skarels return; 274130391Skarels } 274230391Skarels 274330391Skarels adder->ID_scroll_data = scroll[qd]->viper_constant; 274430391Skarels adder->ID_scroll_command = ID_LOAD | SCROLL_CONSTANT; 274530391Skarels 274630391Skarels adder->y_scroll_constant = scroll[qd]->y_scroll_constant; 274730391Skarels adder->y_offset_pending = scroll[qd]->y_offset; 274830391Skarels 274930391Skarels if (scroll[qd]->status & LOAD_INDEX) { 275030391Skarels 275130391Skarels adder->x_index_pending = scroll[qd]->x_index_pending; 275230391Skarels adder->y_index_pending = scroll[qd]->y_index_pending; 275330391Skarels } 275430391Skarels 275530391Skarels scroll[qd]->status = 0x00; 275630391Skarels } 275730391Skarels } 275830391Skarels } 275930391Skarels 276030391Skarels /***************************************************************** 276130391Skarels * 276230391Skarels * qdiint()... DUART input interrupt service routine 276330391Skarels * 276430391Skarels *****************************************************************/ 276530391Skarels 276630391Skarels qdiint(qd) 276730391Skarels register int qd; 276830391Skarels { 276930391Skarels register struct _vs_event *event; 277030391Skarels register struct qdinput *eqh; 277130391Skarels 277230391Skarels struct dga *dga; 277330391Skarels struct duart *duart; 277430391Skarels struct mouse_report *new_rep; 277530391Skarels 277630391Skarels struct uba_device *ui; 277730391Skarels struct tty *tp; 277830391Skarels 2779*34615Smarc u_short chr; 278030391Skarels int i,j; 278130391Skarels int k,l; 278230391Skarels 278330391Skarels u_short status; 278430391Skarels u_short data; 278530391Skarels u_short key; 278630391Skarels 278730391Skarels char do_wakeup = 0; /* flag to do a select wakeup call */ 278830391Skarels char a, b, c; /* mouse button test variables */ 278930391Skarels 279030391Skarels spl4(); /* allow interval timer in */ 279130391Skarels 279230391Skarels eqh = eq_header[qd]; /* optimized as a register */ 279330391Skarels new_rep = ¤t_rep[qd]; 279430391Skarels duart = (struct duart *) qdmap[qd].duart; 279530391Skarels 279630391Skarels /*----------------------------------------- 279730391Skarels * if the graphic device is turned on.. */ 279830391Skarels 279930391Skarels if (qdflags[qd].inuse & GRAPHIC_DEV) { 280030391Skarels 280130391Skarels /*--------------- 280230391Skarels * empty DUART */ 280330391Skarels 280430391Skarels while ((status = duart->statusA) & RCV_RDY || 280530391Skarels (status = duart->statusB) & RCV_RDY) { 280630391Skarels 280730391Skarels /*--------------------------------- 280830391Skarels * pick up LK-201 input (if any) */ 280930391Skarels 281030391Skarels if ((status = duart->statusA) & RCV_RDY) { 281130391Skarels 281230391Skarels /* if error condition, then reset it */ 281330391Skarels 281430391Skarels if ((status = duart->statusA) & 0x70) { 281530391Skarels duart->cmdA = 0x40; 281630391Skarels continue; 281730391Skarels } 281830391Skarels 281930391Skarels /* event queue full now? (overflow condition) */ 282030391Skarels 282130391Skarels if (ISFULL(eqh) == TRUE) { 2822*34615Smarc printf("\nqd%d: qdiint: event queue overflow", qd); 282330391Skarels break; 282430391Skarels } 282530391Skarels 282630391Skarels /*-------------------------------------- 282730391Skarels * Check for various keyboard errors */ 282830391Skarels 282930391Skarels key = duart->dataA & 0xFF; 283030391Skarels 283130391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 283230391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2833*34615Smarc printf("\nqd%d: qdiint: keyboard error, code = %x",qd,key); 283430391Skarels return(0); 283530391Skarels } 283630391Skarels 283730391Skarels if (key < LK_LOWEST) 283830391Skarels return(0); 283930391Skarels 284030391Skarels ++do_wakeup; /* request a select wakeup call */ 284130391Skarels 284230391Skarels event = PUTBEGIN(eqh); 284330391Skarels PUTEND(eqh); 284430391Skarels 284530391Skarels event->vse_key = key; 284630391Skarels event->vse_key &= 0x00FF; 284730391Skarels event->vse_x = eqh->curs_pos.x; 284830391Skarels event->vse_y = eqh->curs_pos.y; 284930391Skarels event->vse_time = TOY; 285030391Skarels event->vse_type = VSE_BUTTON; 285130391Skarels event->vse_direction = VSE_KBTRAW; 285230391Skarels event->vse_device = VSE_DKB; 285330391Skarels } 285430391Skarels 285530391Skarels /*------------------------------------- 285630391Skarels * pick up the mouse input (if any) */ 285730391Skarels 285830391Skarels if ((status = duart->statusB) & RCV_RDY && 285930391Skarels qdflags[qd].pntr_id == MOUSE_ID) { 286030391Skarels 286130391Skarels if (status & 0x70) { 286230391Skarels duart->cmdB = 0x40; 286330391Skarels continue; 286430391Skarels } 286530391Skarels 286630391Skarels /* event queue full now? (overflow condition) */ 286730391Skarels 286830391Skarels if (ISFULL(eqh) == TRUE) { 2869*34615Smarc printf("\nqd%d: qdiint: event queue overflow", qd); 287030391Skarels break; 287130391Skarels } 287230391Skarels 287330391Skarels data = duart->dataB; /* get report byte */ 287430391Skarels ++new_rep->bytcnt; /* bump report byte count */ 287530391Skarels 287630391Skarels /*--------------------------- 287730391Skarels * if 1st byte of report.. */ 287830391Skarels 287930391Skarels if ( data & START_FRAME) { 288030391Skarels new_rep->state = data; 288130391Skarels if (new_rep->bytcnt > 1) { 288230391Skarels new_rep->bytcnt = 1; /* start of new frame */ 288330391Skarels continue; /* ..continue looking */ 288430391Skarels } 288530391Skarels } 288630391Skarels 288730391Skarels /*--------------------------- 288830391Skarels * if 2nd byte of report.. */ 288930391Skarels 289030391Skarels else if (new_rep->bytcnt == 2) { 289130391Skarels new_rep->dx = data & 0x00FF; 289230391Skarels } 289330391Skarels 289430391Skarels /*------------------------------------------------- 289530391Skarels * if 3rd byte of report, load input event queue */ 289630391Skarels 289730391Skarels else if (new_rep->bytcnt == 3) { 289830391Skarels 289930391Skarels new_rep->dy = data & 0x00FF; 290030391Skarels new_rep->bytcnt = 0; 290130391Skarels 290230391Skarels /*----------------------------------- 290330391Skarels * if mouse position has changed.. */ 290430391Skarels 290530391Skarels if (new_rep->dx != 0 || new_rep->dy != 0) { 290630391Skarels 290730391Skarels /*--------------------------------------------- 290830391Skarels * calculate acceleration factor, if needed */ 290930391Skarels 291030391Skarels if (qdflags[qd].curs_acc > ACC_OFF) { 291130391Skarels 291230391Skarels if (qdflags[qd].curs_thr <= new_rep->dx) 291330391Skarels new_rep->dx += 291430391Skarels (new_rep->dx - qdflags[qd].curs_thr) 291530391Skarels * qdflags[qd].curs_acc; 291630391Skarels 291730391Skarels if (qdflags[qd].curs_thr <= new_rep->dy) 291830391Skarels new_rep->dy += 291930391Skarels (new_rep->dy - qdflags[qd].curs_thr) 292030391Skarels * qdflags[qd].curs_acc; 292130391Skarels } 292230391Skarels 292330391Skarels /*------------------------------------- 292430391Skarels * update cursor position coordinates */ 292530391Skarels 292630391Skarels if (new_rep->state & X_SIGN) { 292730391Skarels eqh->curs_pos.x += new_rep->dx; 292830391Skarels if (eqh->curs_pos.x > 1023) 292930391Skarels eqh->curs_pos.x = 1023; 293030391Skarels } 293130391Skarels else { 293230391Skarels eqh->curs_pos.x -= new_rep->dx; 293330391Skarels if (eqh->curs_pos.x < -15) 293430391Skarels eqh->curs_pos.x = -15; 293530391Skarels } 293630391Skarels 293730391Skarels if (new_rep->state & Y_SIGN) { 293830391Skarels eqh->curs_pos.y -= new_rep->dy; 293930391Skarels if (eqh->curs_pos.y < -15) 294030391Skarels eqh->curs_pos.y = -15; 294130391Skarels } 294230391Skarels else { 294330391Skarels eqh->curs_pos.y += new_rep->dy; 294430391Skarels if (eqh->curs_pos.y > 863) 294530391Skarels eqh->curs_pos.y = 863; 294630391Skarels } 294730391Skarels 294830391Skarels /*--------------------------------- 294930391Skarels * update cursor screen position */ 295030391Skarels 295130391Skarels dga = (struct dga *) qdmap[qd].dga; 295230391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 295330391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 295430391Skarels 295530391Skarels /*-------------------------------------------- 295630391Skarels * if cursor is in the box, no event report */ 295730391Skarels 295830391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 295930391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 296030391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 296130391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 296230391Skarels goto GET_MBUTTON; 296330391Skarels } 296430391Skarels 296530391Skarels /*--------------------------------- 296630391Skarels * report the mouse motion event */ 296730391Skarels 296830391Skarels event = PUTBEGIN(eqh); 296930391Skarels PUTEND(eqh); 297030391Skarels 297130391Skarels ++do_wakeup; /* request a select wakeup call */ 297230391Skarels 297330391Skarels event->vse_x = eqh->curs_pos.x; 297430391Skarels event->vse_y = eqh->curs_pos.y; 297530391Skarels 297630391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 297730391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 297830391Skarels event->vse_key = 0; 297930391Skarels event->vse_direction = 0; 298030391Skarels event->vse_time = TOY; /* time stamp */ 298130391Skarels } 298230391Skarels 298330391Skarels GET_MBUTTON: 298430391Skarels /*------------------------------- 298530391Skarels * if button state has changed */ 298630391Skarels 298730391Skarels a = new_rep->state & 0x07; /*mask nonbutton bits */ 298830391Skarels b = last_rep[qd].state & 0x07; 298930391Skarels 299030391Skarels if (a ^ b) { 299130391Skarels 299230391Skarels for ( c = 1; c < 8; c <<= 1) { 299330391Skarels 299430391Skarels if (!( c & (a ^ b))) /* this button change? */ 299530391Skarels continue; 299630391Skarels 299730391Skarels /* event queue full? (overflow condition) */ 299830391Skarels 299930391Skarels if (ISFULL(eqh) == TRUE) { 3000*34615Smarc printf("\nqd%d: qdiint: event queue overflow", qd); 300130391Skarels break; 300230391Skarels } 300330391Skarels 300430391Skarels event = PUTBEGIN(eqh); /* get new event */ 300530391Skarels PUTEND(eqh); 300630391Skarels 300730391Skarels ++do_wakeup; /* request select wakeup */ 300830391Skarels 300930391Skarels event->vse_x = eqh->curs_pos.x; 301030391Skarels event->vse_y = eqh->curs_pos.y; 301130391Skarels 301230391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 301330391Skarels event->vse_type = VSE_BUTTON; /* new button */ 301430391Skarels event->vse_time = TOY; /* time stamp */ 301530391Skarels 301630391Skarels /* flag changed button and if up or down */ 301730391Skarels 301830391Skarels if (c == RIGHT_BUTTON) 301930391Skarels event->vse_key = VSE_RIGHT_BUTTON; 302030391Skarels else if (c == MIDDLE_BUTTON) 302130391Skarels event->vse_key = VSE_MIDDLE_BUTTON; 302230391Skarels else if (c == LEFT_BUTTON) 302330391Skarels event->vse_key = VSE_LEFT_BUTTON; 302430391Skarels 302530391Skarels /* set bit = button depressed */ 302630391Skarels 302730391Skarels if (c & a) 302830391Skarels event->vse_direction = VSE_KBTDOWN; 302930391Skarels else 303030391Skarels event->vse_direction = VSE_KBTUP; 303130391Skarels } 303230391Skarels } 303330391Skarels 303430391Skarels /* refresh last report */ 303530391Skarels 303630391Skarels last_rep[qd] = current_rep[qd]; 303730391Skarels 303830391Skarels } /* get last byte of report */ 303930391Skarels } /* pickup mouse input */ 304030391Skarels 304130391Skarels /*-------------------------------- 304230391Skarels * pickup tablet input, if any */ 304330391Skarels 304430391Skarels else if ((status = duart->statusB) & RCV_RDY && 304530391Skarels qdflags[qd].pntr_id == TABLET_ID) { 304630391Skarels 304730391Skarels if (status & 0x70) { 304830391Skarels duart->cmdB = 0x40; 304930391Skarels continue; 305030391Skarels } 305130391Skarels 305230391Skarels /* event queue full now? (overflow condition) */ 305330391Skarels 305430391Skarels if (ISFULL(eqh) == TRUE) { 3055*34615Smarc printf("\nqd%d: qdiint: event queue overflow", qd); 305630391Skarels break; 305730391Skarels } 305830391Skarels 305930391Skarels data = duart->dataB; /* get report byte */ 306030391Skarels ++new_rep->bytcnt; /* bump report byte count */ 306130391Skarels 306230391Skarels /*--------------------------- 306330391Skarels * if 1st byte of report.. */ 306430391Skarels 306530391Skarels if (data & START_FRAME) { 306630391Skarels new_rep->state = data; 306730391Skarels if (new_rep->bytcnt > 1) { 306830391Skarels new_rep->bytcnt = 1; /* start of new frame */ 306930391Skarels continue; /* ..continue looking */ 307030391Skarels } 307130391Skarels } 307230391Skarels 307330391Skarels /*--------------------------- 307430391Skarels * if 2nd byte of report.. */ 307530391Skarels 307630391Skarels else if (new_rep->bytcnt == 2) { 307730391Skarels new_rep->dx = data & 0x3F; 307830391Skarels } 307930391Skarels 308030391Skarels /*--------------------------- 308130391Skarels * if 3rd byte of report.. */ 308230391Skarels 308330391Skarels else if (new_rep->bytcnt == 3) { 308430391Skarels new_rep->dx |= (data & 0x3F) << 6; 308530391Skarels } 308630391Skarels 308730391Skarels /*--------------------------- 308830391Skarels * if 4th byte of report.. */ 308930391Skarels 309030391Skarels else if (new_rep->bytcnt == 4) { 309130391Skarels new_rep->dy = data & 0x3F; 309230391Skarels } 309330391Skarels 309430391Skarels /*------------------------------------------------- 309530391Skarels * if 5th byte of report, load input event queue */ 309630391Skarels 309730391Skarels else if (new_rep->bytcnt == 5) { 309830391Skarels 309930391Skarels new_rep->dy |= (data & 0x3F) << 6; 310030391Skarels new_rep->bytcnt = 0; 310130391Skarels 310230391Skarels /*------------------------------------- 310330391Skarels * update cursor position coordinates */ 310430391Skarels 310530391Skarels new_rep->dx /= qdflags[qd].tab_res; 310630391Skarels new_rep->dy = (2200 - new_rep->dy) 310730391Skarels / qdflags[qd].tab_res; 310830391Skarels 310930391Skarels if (new_rep->dx > 1023) { 311030391Skarels new_rep->dx = 1023; 311130391Skarels } 311230391Skarels if (new_rep->dy > 863) { 311330391Skarels new_rep->dy = 863; 311430391Skarels } 311530391Skarels 311630391Skarels /* 311730391Skarels * report an event if the puck/stylus has moved 311830391Skarels */ 311930391Skarels 312030391Skarels if (eqh->curs_pos.x != new_rep->dx || 312130391Skarels eqh->curs_pos.y != new_rep->dy) { 312230391Skarels 312330391Skarels eqh->curs_pos.x = new_rep->dx; 312430391Skarels eqh->curs_pos.y = new_rep->dy; 312530391Skarels 312630391Skarels /*--------------------------------- 312730391Skarels * update cursor screen position */ 312830391Skarels 312930391Skarels dga = (struct dga *) qdmap[qd].dga; 313030391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 313130391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 313230391Skarels 313330391Skarels /* 313430391Skarels * if cursor is in the box, no event report 313530391Skarels */ 313630391Skarels 313730391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 313830391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 313930391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 314030391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 314130391Skarels goto GET_TBUTTON; 314230391Skarels } 314330391Skarels 314430391Skarels /*--------------------------------- 314530391Skarels * report the tablet motion event */ 314630391Skarels 314730391Skarels event = PUTBEGIN(eqh); 314830391Skarels PUTEND(eqh); 314930391Skarels 315030391Skarels ++do_wakeup; /* request a select wakeup call */ 315130391Skarels 315230391Skarels event->vse_x = eqh->curs_pos.x; 315330391Skarels event->vse_y = eqh->curs_pos.y; 315430391Skarels 315530391Skarels event->vse_device = VSE_TABLET; /* tablet */ 315630391Skarels /* 315730391Skarels * right now, X handles tablet motion the same 315830391Skarels * as mouse motion 315930391Skarels */ 316030391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 316130391Skarels event->vse_key = 0; 316230391Skarels event->vse_direction = 0; 316330391Skarels event->vse_time = TOY; /* time stamp */ 316430391Skarels } 316530391Skarels GET_TBUTTON: 316630391Skarels /*------------------------------- 316730391Skarels * if button state has changed */ 316830391Skarels 316930391Skarels a = new_rep->state & 0x1E; /* mask nonbutton bits */ 317030391Skarels b = last_rep[qd].state & 0x1E; 317130391Skarels 317230391Skarels if (a ^ b) { 317330391Skarels 317430391Skarels /* event queue full now? (overflow condition) */ 317530391Skarels 317630391Skarels if (ISFULL(eqh) == TRUE) { 3177*34615Smarc printf("\nqd%d: qdiint: event queue overflow",qd); 317830391Skarels break; 317930391Skarels } 318030391Skarels 318130391Skarels event = PUTBEGIN(eqh); /* get new event */ 318230391Skarels PUTEND(eqh); 318330391Skarels 318430391Skarels ++do_wakeup; /* request a select wakeup call */ 318530391Skarels 318630391Skarels event->vse_x = eqh->curs_pos.x; 318730391Skarels event->vse_y = eqh->curs_pos.y; 318830391Skarels 318930391Skarels event->vse_device = VSE_TABLET; /* tablet */ 319030391Skarels event->vse_type = VSE_BUTTON; /* button changed */ 319130391Skarels event->vse_time = TOY; /* time stamp */ 319230391Skarels 319330391Skarels /* define the changed button and if up or down */ 319430391Skarels 319530391Skarels for ( c = 1; c <= 0x10; c <<= 1) { 319630391Skarels if (c & (a ^ b)) { 319730391Skarels if (c == T_LEFT_BUTTON) 319830391Skarels event->vse_key = VSE_T_LEFT_BUTTON; 319930391Skarels else if (c == T_FRONT_BUTTON) 320030391Skarels event->vse_key = VSE_T_FRONT_BUTTON; 320130391Skarels else if (c == T_RIGHT_BUTTON) 320230391Skarels event->vse_key = VSE_T_RIGHT_BUTTON; 320330391Skarels else if (c == T_BACK_BUTTON) 320430391Skarels event->vse_key = VSE_T_BACK_BUTTON; 320530391Skarels break; 320630391Skarels } 320730391Skarels } 320830391Skarels 320930391Skarels /* set bit = button depressed */ 321030391Skarels 321130391Skarels if (c & a) 321230391Skarels event->vse_direction = VSE_KBTDOWN; 321330391Skarels else 321430391Skarels event->vse_direction = VSE_KBTUP; 321530391Skarels } 321630391Skarels 321730391Skarels /* refresh last report */ 321830391Skarels 321930391Skarels last_rep[qd] = current_rep[qd]; 322030391Skarels 322130391Skarels } /* get last byte of report */ 322230391Skarels } /* pick up tablet input */ 322330391Skarels 322430391Skarels } /* while input available.. */ 322530391Skarels 322630391Skarels /*--------------------- 322730391Skarels * do select wakeup */ 322830391Skarels 3229*34615Smarc 323030391Skarels if (rsel[qd] && do_wakeup && qdflags[qd].selmask & SEL_READ) { 323130391Skarels selwakeup(rsel[qd], 0); 323230391Skarels rsel[qd] = 0; 323330391Skarels qdflags[qd].selmask &= ~SEL_READ; 323430391Skarels do_wakeup = 0; 323530391Skarels } 323630391Skarels } 323730391Skarels 3238*34615Smarc /*----------------------------------------------------------------- 3239*34615Smarc * if the graphic device is not turned on, this is console input */ 324030391Skarels 324130391Skarels else { 324230391Skarels 324330391Skarels ui = qdinfo[qd]; 324430391Skarels if (ui == 0 || ui->ui_alive == 0) 324530391Skarels return(0); 324630391Skarels 324730391Skarels tp = &qd_tty[qd << 2]; 324830391Skarels 324930391Skarels /*-------------------------------------- 325030391Skarels * Get a character from the keyboard. */ 325130391Skarels 325230391Skarels while ((status = duart->statusA) & RCV_RDY) { 325330391Skarels 325430391Skarels key = duart->dataA; 325530391Skarels key &= 0xFF; 325630391Skarels 325730391Skarels /*-------------------------------------- 325830391Skarels * Check for various keyboard errors */ 325930391Skarels 326030391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 326130391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 3262*34615Smarc printf("\nqd%d: qdiint: Keyboard error, code = %x",qd,key); 326330391Skarels return(0); 326430391Skarels } 326530391Skarels 326630391Skarels if (key < LK_LOWEST) 326730391Skarels return(0); 326830391Skarels 326930391Skarels /*--------------------------------- 327030391Skarels * See if its a state change key */ 327130391Skarels 327230391Skarels switch (key) { 327330391Skarels 327430391Skarels case LOCK: 327530391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 327630391Skarels if (q_keyboard.lock) 327730391Skarels led_control(qd, LK_LED_ENABLE, LK_LED_LOCK); 327830391Skarels else 327930391Skarels led_control(qd, LK_LED_DISABLE, LK_LED_LOCK); 328030391Skarels return; 328130391Skarels 328230391Skarels case SHIFT: 328330391Skarels q_keyboard.shift ^= 0xFFFF; 328430391Skarels return; 328530391Skarels 328630391Skarels case CNTRL: 328730391Skarels q_keyboard.cntrl ^= 0xFFFF; 328830391Skarels return; 328930391Skarels 329030391Skarels case ALLUP: 329130391Skarels q_keyboard.cntrl = 0; 329230391Skarels q_keyboard.shift = 0; 329330391Skarels return; 329430391Skarels 329530391Skarels case REPEAT: 329630391Skarels chr = q_keyboard.last; 329730391Skarels break; 329830391Skarels 329930391Skarels /*------------------------------------------------------- 330030391Skarels * Test for cntrl characters. If set, see if the character 330130391Skarels * is elligible to become a control character. */ 330230391Skarels 330330391Skarels default: 330430391Skarels 330530391Skarels if (q_keyboard.cntrl) { 330630391Skarels chr = q_key[key]; 330730391Skarels if (chr >= ' ' && chr <= '~') 330830391Skarels chr &= 0x1F; 3309*34615Smarc else if (chr >= 0xA1 && chr <= 0xFE) 3310*34615Smarc chr &= 0x9F; 331130391Skarels } 331230391Skarels else if( q_keyboard.lock || q_keyboard.shift ) 331330391Skarels chr = q_shift_key[key]; 331430391Skarels else 331530391Skarels chr = q_key[key]; 331630391Skarels break; 331730391Skarels } 331830391Skarels 331930391Skarels q_keyboard.last = chr; 332030391Skarels 332130391Skarels /*----------------------------------- 332230391Skarels * Check for special function keys */ 332330391Skarels 3324*34615Smarc if (chr & 0x100) { 332530391Skarels char *string; 332630391Skarels string = q_special[chr & 0x7F]; 332730391Skarels while(*string) 332830391Skarels (*linesw[tp->t_line].l_rint)(*string++, tp); 332930391Skarels } 333030391Skarels else { 3331*34615Smarc #ifdef notdef /* notneeded */ 3332*34615Smarc if (tp->t_iflag & ISTRIP) /* Strip to 7 bits. */ 3333*34615Smarc c &= 0177; 3334*34615Smarc else { /* Take the full 8-bits */ 3335*34615Smarc /* If ISTRIP is not set a valid character of 377 3336*34615Smarc * is read as 0377,0377 to avoid ambiguity with 3337*34615Smarc * the PARMARK sequence. 3338*34615Smarc */ 3339*34615Smarc if ((c == 0377) && (tp->t_line == TERMIODISC)) 3340*34615Smarc (*linesw[tp->t_line].l_rint)(0377,tp); 3341*34615Smarc 3342*34615Smarc } 3343*34615Smarc #endif /*notdef*/ 334430391Skarels (*linesw[tp->t_line].l_rint)(chr, tp); 334530391Skarels } 334630391Skarels } 334730391Skarels } 334830391Skarels 3349*34615Smarc /*---------------------- 3350*34615Smarc * cleanup and exit */ 3351*34615Smarc 335230391Skarels return(0); 335330391Skarels 335430391Skarels } /* qdiint */ 335530391Skarels 335630391Skarels /****************************************************************** 3357*34615Smarc ******************************************************************* 3358*34615Smarc ******************************************************************* 335930391Skarels * 336030391Skarels * THE SUBROUTINES START HERE: 336130391Skarels * 336230391Skarels ******************************************************************/ 336330391Skarels 336430391Skarels /***************************************************************** 336530391Skarels * 336630391Skarels * clear_qd_screen()... clear the QDSS screen 336730391Skarels * 336830391Skarels ****************************************************************** 336930391Skarels * 337030391Skarels * >>> NOTE <<< 337130391Skarels * 337230391Skarels * This code requires that certain adder initialization be valid. To 337330391Skarels * assure that this requirement is satisfied, this routine should be 337430391Skarels * called only after calling the "setup_dragon()" function. 337530391Skarels * 337630391Skarels * Clear the bitmap a piece at a time. Since the fast scroll clear 337730391Skarels * only clears the current displayed portion of the bitmap put a 337830391Skarels * temporary value in the y limit register so we can access whole 337930391Skarels * bitmap 338030391Skarels * 338130391Skarels ****************/ 338230391Skarels 338330391Skarels clear_qd_screen(unit) 338430391Skarels int unit; 338530391Skarels { 338630391Skarels register struct adder *adder; 338730391Skarels adder = (struct adder *) qdmap[unit].adder; 338830391Skarels 338930391Skarels adder->x_limit = 1024; 339030391Skarels adder->y_limit = 2048 - CHAR_HEIGHT; 339130391Skarels adder->y_offset_pending = 0; 339230391Skarels 339330391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 339430391Skarels wait_status(adder, VSYNC); 339530391Skarels 339630391Skarels adder->y_scroll_constant = SCROLL_ERASE; 339730391Skarels 339830391Skarels wait_status(adder, VSYNC); 339930391Skarels wait_status(adder, VSYNC); 340030391Skarels 340130391Skarels adder->y_offset_pending = 864; 340230391Skarels 340330391Skarels wait_status(adder, VSYNC); 340430391Skarels wait_status(adder, VSYNC); 340530391Skarels 340630391Skarels adder->y_scroll_constant = SCROLL_ERASE; 340730391Skarels 340830391Skarels wait_status(adder, VSYNC); 340930391Skarels wait_status(adder, VSYNC); 341030391Skarels 341130391Skarels adder->y_offset_pending = 1728; 341230391Skarels 341330391Skarels wait_status(adder, VSYNC); 341430391Skarels wait_status(adder, VSYNC); 341530391Skarels 341630391Skarels adder->y_scroll_constant = SCROLL_ERASE; 341730391Skarels 341830391Skarels wait_status(adder, VSYNC); 341930391Skarels wait_status(adder, VSYNC); 342030391Skarels 342130391Skarels adder->y_offset_pending = 0; /* back to normal */ 342230391Skarels 342330391Skarels wait_status(adder, VSYNC); 342430391Skarels wait_status(adder, VSYNC); 342530391Skarels 342630391Skarels adder->x_limit = MAX_SCREEN_X; 342730391Skarels adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; 342830391Skarels 342930391Skarels } /* clear_qd_screen */ 343030391Skarels 343130391Skarels /********************************************************************** 343230391Skarels * 343330391Skarels * qdputc()... route kernel console output to display destination 343430391Skarels * 343530391Skarels *********************************************************************** 343630391Skarels * 343730391Skarels * calling convention: 343830391Skarels * 343930391Skarels * qdputc(chr); 344030391Skarels * 344130391Skarels * where: char chr; ;character for output 344230391Skarels * 344330391Skarels ****************/ 344430391Skarels 344530391Skarels qdputc(chr) 344630391Skarels register char chr; 344730391Skarels { 3448*34615Smarc register struct tty *tp0; 344930391Skarels 3450*34615Smarc /*--------------------------------------------------------- 3451*34615Smarc * if system is now physical, forget it (ie: crash DUMP) */ 3452*34615Smarc 345330391Skarels if ( (mfpr(MAPEN) & 1) == 0 ) 345430391Skarels return; 345530391Skarels 3456*34615Smarc /*-------------------------------------------------- 3457*34615Smarc * direct kernel output char to the proper place */ 3458*34615Smarc 3459*34615Smarc #ifdef notdef /* never */ 3460*34615Smarc tp0 = &qd_tty[1]; 3461*34615Smarc 3462*34615Smarc if (qdflags[0].kernel_loop != 0 && tp0->t_state & TS_ISOPEN) { 3463*34615Smarc (*linesw[tp0->t_line].l_rint)(chr, tp0); 3464*34615Smarc } else { 3465*34615Smarc blitc(0, chr & 0xff); 3466*34615Smarc } 3467*34615Smarc #endif /*notdef*/ 3468*34615Smarc blitc(0, chr & 0xff); 346932012Smarc if ((chr & 0177) == '\n') 347032012Smarc blitc(0, '\r'); 347130391Skarels 347230391Skarels 347330391Skarels } /* qdputc */ 347430391Skarels 347530391Skarels /******************************************************************* 347630391Skarels * 347730391Skarels * qdgetc()... get a character from the LK201 347830391Skarels * 347930391Skarels ******************************************************************* 348030391Skarels * 348130391Skarels * calling convention: 348230391Skarels * 348330391Skarels * qdgetc(); 348430391Skarels * 348530391Skarels * returns: the character read. 348630391Skarels * 348730391Skarels ****************/ 348830391Skarels 348930391Skarels qdgetc() 349030391Skarels { 349130391Skarels register short key; 349230391Skarels register char chr; 349330391Skarels register struct duart *duart; 349430391Skarels 349530391Skarels u_int status; 349630391Skarels 349730391Skarels duart = (struct duart *) qdmap[0].duart; 349830391Skarels 349930391Skarels /*-------------------------------------- 350030391Skarels * Get a character from the keyboard. */ 350130391Skarels 350230391Skarels LOOP: 350330391Skarels while (!((status = duart->statusA) & RCV_RDY)) 350430391Skarels ; 350530391Skarels 350630391Skarels key = duart->dataA; 350730391Skarels key &= 0xFF; 350830391Skarels 350930391Skarels /*-------------------------------------- 351030391Skarels * Check for various keyboard errors */ 351130391Skarels 351230391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 351330391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 351430391Skarels printf("Keyboard error, code = %x\n", key); 351530391Skarels return(0); 351630391Skarels } 351730391Skarels 351830391Skarels if (key < LK_LOWEST) 351930391Skarels return(0); 352030391Skarels 352130391Skarels /*--------------------------------- 352230391Skarels * See if its a state change key */ 352330391Skarels 352430391Skarels switch (key) { 352530391Skarels 352630391Skarels case LOCK: 352730391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 352830391Skarels if (q_keyboard.lock) 352930391Skarels led_control(LK_LED_ENABLE, LK_LED_LOCK); 353030391Skarels else 353130391Skarels led_control(LK_LED_DISABLE, LK_LED_LOCK); 353230391Skarels goto LOOP; 353330391Skarels 353430391Skarels case SHIFT: 353530391Skarels q_keyboard.shift ^= 0xFFFF; 353630391Skarels goto LOOP; 353730391Skarels 353830391Skarels case CNTRL: 353930391Skarels q_keyboard.cntrl ^= 0xFFFF; 354030391Skarels goto LOOP; 354130391Skarels 354230391Skarels case ALLUP: 354330391Skarels q_keyboard.cntrl = 0; 354430391Skarels q_keyboard.shift = 0; 354530391Skarels goto LOOP; 354630391Skarels 354730391Skarels case REPEAT: 354830391Skarels chr = q_keyboard.last; 354930391Skarels break; 355030391Skarels 355130391Skarels /*------------------------------------------------------- 355230391Skarels * Test for cntrl characters. If set, see if the character 355330391Skarels * is elligible to become a control character. */ 355430391Skarels 355530391Skarels default: 355630391Skarels 355730391Skarels if (q_keyboard.cntrl) { 355830391Skarels chr = q_key[key]; 355930391Skarels if (chr >= ' ' && chr <= '~') 356030391Skarels chr &= 0x1F; 356130391Skarels } 356230391Skarels else if ( q_keyboard.lock || q_keyboard.shift ) 356330391Skarels chr = q_shift_key[key]; 356430391Skarels else 356530391Skarels chr = q_key[key]; 356630391Skarels break; 356730391Skarels } 356830391Skarels 356930391Skarels if (chr < ' ' && chr > '~') /* if input is non-displayable */ 357030391Skarels return(0); /* ..then pitch it! */ 357130391Skarels 357230391Skarels q_keyboard.last = chr; 357330391Skarels 357430391Skarels /*----------------------------------- 357530391Skarels * Check for special function keys */ 357630391Skarels 357730391Skarels if (chr & 0x80) /* pitch the function keys */ 357830391Skarels return(0); 357930391Skarels else 358030391Skarels return(chr); 358130391Skarels 358230391Skarels } /* qdgetc */ 358330391Skarels 358430391Skarels /********************************************************************** 358530391Skarels * 358630391Skarels * ldcursor()... load the mouse cursor's template RAM bitmap 358730391Skarels * 358830391Skarels ********************************************************************* 358930391Skarels * 359030391Skarels * calling convention: 359130391Skarels * 359230391Skarels * ldcursor(unit, bitmap); 359330391Skarels * u_int unit; 359430391Skarels * short *bitmap; 359530391Skarels * 359630391Skarels ****************/ 359730391Skarels 359830391Skarels ldcursor(unit, bitmap) 359930391Skarels u_int unit; 360030391Skarels short *bitmap; 360130391Skarels { 360230391Skarels register struct dga *dga; 360330391Skarels register short *temp; 360430391Skarels register int i; 360530391Skarels 360630391Skarels int cursor; 360730391Skarels 360830391Skarels dga = (struct dga *) qdmap[unit].dga; 360930391Skarels temp = (short *) qdmap[unit].template; 361030391Skarels 361130391Skarels if (dga->csr & CURS_ENB) { /* if the cursor is enabled.. */ 361230391Skarels cursor = -1; /* ..note that.. */ 361330391Skarels dga->csr &= ~CURS_ENB; /* ..and shut it off */ 361430391Skarels } 361530391Skarels else { 361630391Skarels cursor = 0; 361730391Skarels } 361830391Skarels 361930391Skarels dga->csr &= ~CURS_ENB; /* shut off the cursor */ 362030391Skarels 362130391Skarels temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ 362230391Skarels /* ..of the 8k WORD template space */ 362330391Skarels for (i = 0; i < 32; ++i) 362430391Skarels *temp++ = *bitmap++; 362530391Skarels 362630391Skarels if (cursor) { /* if cursor was enabled.. */ 362730391Skarels dga->csr |= CURS_ENB; /* ..turn it back on */ 362830391Skarels } 362930391Skarels 363030391Skarels return(0); 363130391Skarels 363230391Skarels } /* ldcursor */ 363330391Skarels 363430391Skarels /********************************************************************** 363530391Skarels * 363630391Skarels * ldfont()... put the console font in the QDSS off-screen memory 363730391Skarels * 363830391Skarels *********************************************************************** 363930391Skarels * 364030391Skarels * calling convention: 364130391Skarels * 364230391Skarels * ldfont(unit); 364330391Skarels * u_int unit; ;QDSS unit number 364430391Skarels * 364530391Skarels ****************/ 364630391Skarels 364730391Skarels ldfont(unit) 364830391Skarels u_int unit; 364930391Skarels { 365030391Skarels register struct adder *adder; 365130391Skarels 365230391Skarels int i; /* scratch variables */ 365330391Skarels int j; 365430391Skarels int k; 365530391Skarels short packed; 3656*34615Smarc int max_chars_line; 365730391Skarels 365830391Skarels adder = (struct adder *) qdmap[unit].adder; 365930391Skarels 3660*34615Smarc /*------------------------------------------ 3661*34615Smarc * setup VIPER operand control registers */ 366230391Skarels 366330391Skarels write_ID(adder, MASK_1, 0xFFFF); 366430391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 366530391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 366630391Skarels 366730391Skarels write_ID(adder, SRC1_OCR_B, 366830391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 366930391Skarels write_ID(adder, SRC2_OCR_B, 367030391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 367130391Skarels write_ID(adder, DST_OCR_B, 367230391Skarels EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 367330391Skarels 367430391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 367530391Skarels 3676*34615Smarc /*-------------------------- 3677*34615Smarc * load destination data */ 367830391Skarels 367930391Skarels wait_status(adder, RASTEROP_COMPLETE); 368030391Skarels 368130391Skarels adder->destination_x = FONT_X; 368230391Skarels adder->destination_y = FONT_Y; 3683*34615Smarc if (FONT_WIDTH > MAX_SCREEN_X) 3684*34615Smarc adder->fast_dest_dx = MAX_SCREEN_X; 3685*34615Smarc else 3686*34615Smarc adder->fast_dest_dx = FONT_WIDTH; 368730391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 368830391Skarels 3689*34615Smarc /*--------------------------------------- 3690*34615Smarc * setup for processor to bitmap xfer */ 369130391Skarels 369230391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 369330391Skarels adder->cmd = PBT | OCRB | 2 | DTE | 2; 369430391Skarels 3695*34615Smarc /*--------------------------------------- 3696*34615Smarc * Figure out how many characters can be stored on one "line" of offscreen memory 3697*34615Smarc */ 3698*34615Smarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3699*34615Smarc if ((CHARS/2 + CHARS%2) < max_chars_line) 3700*34615Smarc max_chars_line = CHARS/2 + CHARS%2; 370130391Skarels 3702*34615Smarc /*----------------------------------------------- 3703*34615Smarc * iteratively do the processor to bitmap xfer */ 3704*34615Smarc 370530391Skarels for (i = 0; i < ROWS; ++i) { 370630391Skarels 370730391Skarels /* PTOB a scan line */ 370830391Skarels 3709*34615Smarc for (j = 0, k = i; j < max_chars_line; ++j) { 371030391Skarels /* PTOB one scan of a char cell */ 371130391Skarels 371230391Skarels packed = q_font[k]; 371330391Skarels k += ROWS; 371430391Skarels packed |= ((short)q_font[k] << 8); 371530391Skarels k += ROWS; 371630391Skarels 371730391Skarels wait_status(adder, TX_READY); 371830391Skarels adder->id_data = packed; 371930391Skarels } 372030391Skarels } 372130391Skarels 3722*34615Smarc /*--------------------------------------- 3723*34615Smarc * Copy the second row of characters. 3724*34615Smarc * Subtract the first row from the total number. Divide this quantity by 2 3725*34615Smarc * because 2 chars are stored in a short in the PTOB loop below. 3726*34615Smarc * Figure out how many characters can be stored on one "line" of offscreen memory 3727*34615Smarc */ 3728*34615Smarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3729*34615Smarc if ((CHARS/2 + CHARS%2) < max_chars_line) 3730*34615Smarc return; 3731*34615Smarc max_chars_line = (CHARS/2 + CHARS%2) - max_chars_line; /* 95 - 64 */ 3732*34615Smarc /* Paranoia check to see if 3rd row may be needed */ 3733*34615Smarc if (max_chars_line > (MAX_SCREEN_X/(CHAR_WIDTH*2))) 3734*34615Smarc max_chars_line = MAX_SCREEN_X/(CHAR_WIDTH*2); 3735*34615Smarc 3736*34615Smarc 3737*34615Smarc /*-----------------------------------------------*/ 3738*34615Smarc 3739*34615Smarc adder->destination_x = FONT_X; 3740*34615Smarc adder->destination_y = FONT_Y - CHAR_HEIGHT; 3741*34615Smarc adder->fast_dest_dx = max_chars_line * CHAR_WIDTH * 2; 3742*34615Smarc adder->slow_dest_dy = CHAR_HEIGHT; 3743*34615Smarc 3744*34615Smarc /*--------------------------------------- 3745*34615Smarc * setup for processor to bitmap xfer */ 3746*34615Smarc 3747*34615Smarc write_ID(adder, CS_UPDATE_MASK, 0x0001); 3748*34615Smarc adder->cmd = PBT | OCRB | 2 | DTE | 2; 3749*34615Smarc 3750*34615Smarc /*----------------------------------------------- 3751*34615Smarc * iteratively do the processor to bitmap xfer */ 3752*34615Smarc 3753*34615Smarc for (i = 0; i < ROWS; ++i) { 3754*34615Smarc 3755*34615Smarc /* PTOB a scan line */ 3756*34615Smarc 3757*34615Smarc for (j = 0, k = i; j < max_chars_line; ++j) { 3758*34615Smarc 3759*34615Smarc /* PTOB one scan of a char cell */ 3760*34615Smarc 3761*34615Smarc packed = q_font[k + FONT_OFFSET]; 3762*34615Smarc k += ROWS; 3763*34615Smarc packed |= ((short)q_font[k + FONT_OFFSET] << 8); 3764*34615Smarc k += ROWS; 3765*34615Smarc 3766*34615Smarc wait_status(adder, TX_READY); 3767*34615Smarc adder->id_data = packed; 3768*34615Smarc } 3769*34615Smarc } 3770*34615Smarc 377130391Skarels } /* ldfont */ 377230391Skarels 377330391Skarels /********************************************************************* 377430391Skarels * 377530391Skarels * led_control()... twiddle LK-201 LED's 377630391Skarels * 377730391Skarels ********************************************************************** 377830391Skarels * 377930391Skarels * led_control(unit, cmd, led_mask); 378030391Skarels * u_int unit; QDSS number 378130391Skarels * int cmd; LED enable/disable command 378230391Skarels * int led_mask; which LED(s) to twiddle 378330391Skarels * 378430391Skarels *************/ 378530391Skarels 378630391Skarels led_control(unit, cmd, led_mask) 378730391Skarels u_int unit; 378830391Skarels int cmd; 378930391Skarels int led_mask; 379030391Skarels { 379130391Skarels register int i; 379230391Skarels register int status; 379330391Skarels register struct duart *duart; 379430391Skarels 379530391Skarels duart = (struct duart *) qdmap[unit].duart; 379630391Skarels 379730391Skarels for (i = 1000; i > 0; --i) { 379830391Skarels if ((status = duart->statusA) & XMT_RDY) { 379930391Skarels duart->dataA = cmd; 380030391Skarels break; 380130391Skarels } 380230391Skarels } 380330391Skarels 380430391Skarels for (i = 1000; i > 0; --i) { 380530391Skarels if ((status = duart->statusA) & XMT_RDY) { 380630391Skarels duart->dataA = led_mask; 380730391Skarels break; 380830391Skarels } 380930391Skarels } 381030391Skarels 381130391Skarels if (i == 0) 381230391Skarels return(BAD); 381330391Skarels 381430391Skarels return(GOOD); 381530391Skarels 381630391Skarels } /* led_control */ 381730391Skarels 381830391Skarels /******************************************************************* 381930391Skarels * 382030391Skarels * scroll_up()... move the screen up one character height 382130391Skarels * 382230391Skarels ******************************************************************** 382330391Skarels * 382430391Skarels * calling convention: 382530391Skarels * 382630391Skarels * scroll_up(adder); 382730391Skarels * struct adder *adder; ;address of adder 382830391Skarels * 382930391Skarels ********/ 383030391Skarels 383130391Skarels scroll_up(adder) 383230391Skarels register struct adder *adder; 383330391Skarels { 383430391Skarels 3835*34615Smarc /*------------------------------------------ 3836*34615Smarc * setup VIPER operand control registers */ 383730391Skarels 383830391Skarels wait_status(adder, ADDRESS_COMPLETE); 383930391Skarels 384030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 384130391Skarels 384230391Skarels write_ID(adder, MASK_1, 0xFFFF); 384330391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 384430391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 384530391Skarels 384630391Skarels write_ID(adder, SRC1_OCR_B, 384730391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 384830391Skarels write_ID(adder, DST_OCR_B, 384930391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 385030391Skarels 3851*34615Smarc /*---------------------------------------- 3852*34615Smarc * load DESTINATION origin and vectors */ 385330391Skarels 385430391Skarels adder->fast_dest_dy = 0; 385530391Skarels adder->slow_dest_dx = 0; 385630391Skarels adder->error_1 = 0; 385730391Skarels adder->error_2 = 0; 385830391Skarels 385930391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 386030391Skarels 386130391Skarels adder->destination_x = 0; 386230391Skarels adder->fast_dest_dx = 1024; 386330391Skarels 386430391Skarels adder->destination_y = 0; 386530391Skarels adder->slow_dest_dy = 864 - CHAR_HEIGHT; 386630391Skarels 3867*34615Smarc /*----------------------------------- 3868*34615Smarc * load SOURCE origin and vectors */ 386930391Skarels 387030391Skarels adder->source_1_x = 0; 387130391Skarels adder->source_1_dx = 1024; 387230391Skarels 387330391Skarels adder->source_1_y = 0 + CHAR_HEIGHT; 387430391Skarels adder->source_1_dy = 864 - CHAR_HEIGHT; 387530391Skarels 387630391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 387730391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 387830391Skarels 3879*34615Smarc /*-------------------------------------------- 3880*34615Smarc * do a rectangle clear of last screen line */ 388130391Skarels 388230391Skarels write_ID(adder, MASK_1, 0xffff); 388330391Skarels write_ID(adder, SOURCE, 0xffff); 388430391Skarels write_ID(adder,DST_OCR_B, 388530391Skarels (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); 388630391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); 388730391Skarels adder->error_1 = 0; 388830391Skarels adder->error_2 = 0; 388930391Skarels adder->slow_dest_dx = 0; /* set up the width of */ 389030391Skarels adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ 389130391Skarels 389230391Skarels adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; 389330391Skarels wait_status(adder, RASTEROP_COMPLETE); 389430391Skarels adder->destination_x = 0; 389530391Skarels adder->destination_y = 864 - CHAR_HEIGHT; 389630391Skarels 389730391Skarels adder->fast_dest_dx = 1024; /* set up the height */ 389830391Skarels adder->fast_dest_dy = 0; /* of rectangle */ 389930391Skarels 390030391Skarels write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); 390130391Skarels adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; 390230391Skarels 390330391Skarels } /* scroll_up */ 390430391Skarels 390530391Skarels /******************************************************************** 390630391Skarels * 390730391Skarels * init_shared()... init shared memory pointers and structures 390830391Skarels * 390930391Skarels ********************************************************************* 391030391Skarels * 391130391Skarels * calling convention: 391230391Skarels * 391330391Skarels * init_shared(unit); 391430391Skarels * u_int unit; 391530391Skarels * 391630391Skarels ****************/ 391730391Skarels 391830391Skarels init_shared(unit) 391930391Skarels register u_int unit; 392030391Skarels { 392130391Skarels register struct dga *dga; 392230391Skarels 392330391Skarels dga = (struct dga *) qdmap[unit].dga; 392430391Skarels 3925*34615Smarc /*-------------------------------------------------- 3926*34615Smarc * initialize the event queue pointers and header */ 392730391Skarels 392830391Skarels eq_header[unit] = (struct qdinput *) 392930391Skarels ((((int)event_shared & ~(0x01FF)) + 512) 393030391Skarels + (EVENT_BUFSIZE * unit)); 393130391Skarels 393230391Skarels eq_header[unit]->curs_pos.x = 0; 393330391Skarels eq_header[unit]->curs_pos.y = 0; 393430391Skarels 393530391Skarels dga->x_cursor = TRANX(eq_header[unit]->curs_pos.x); 393630391Skarels dga->y_cursor = TRANY(eq_header[unit]->curs_pos.y); 393730391Skarels 393830391Skarels eq_header[unit]->curs_box.left = 0; 393930391Skarels eq_header[unit]->curs_box.right = 0; 394030391Skarels eq_header[unit]->curs_box.top = 0; 394130391Skarels eq_header[unit]->curs_box.bottom = 0; 394230391Skarels 3943*34615Smarc /*--------------------------------------------------------- 3944*34615Smarc * assign a pointer to the DMA I/O buffer for this QDSS. */ 394530391Skarels 394630391Skarels DMAheader[unit] = (struct DMAreq_header *) 394730391Skarels (((int)(&DMA_shared[0] + 512) & ~0x1FF) 394830391Skarels + (DMAbuf_size * unit)); 394930391Skarels 395030391Skarels DMAheader[unit]->DMAreq = (struct DMAreq *) ((int)DMAheader[unit] 395130391Skarels + sizeof(struct DMAreq_header)); 395230391Skarels 395330391Skarels DMAheader[unit]->QBAreg = 0; 395430391Skarels DMAheader[unit]->status = 0; 395530391Skarels DMAheader[unit]->shared_size = DMAbuf_size; 395630391Skarels DMAheader[unit]->used = 0; 395730391Skarels DMAheader[unit]->size = 10; /* default = 10 requests */ 395830391Skarels DMAheader[unit]->oldest = 0; 395930391Skarels DMAheader[unit]->newest = 0; 396030391Skarels 3961*34615Smarc /*----------------------------------------------------------- 3962*34615Smarc * assign a pointer to the scroll structure for this QDSS. */ 396330391Skarels 396430391Skarels scroll[unit] = (struct scroll *) 396530391Skarels (((int)(&scroll_shared[0] + 512) & ~0x1FF) 396630391Skarels + (sizeof(struct scroll) * unit)); 396730391Skarels 396830391Skarels scroll[unit]->status = 0; 396930391Skarels scroll[unit]->viper_constant = 0; 397030391Skarels scroll[unit]->y_scroll_constant = 0; 397130391Skarels scroll[unit]->y_offset = 0; 397230391Skarels scroll[unit]->x_index_pending = 0; 397330391Skarels scroll[unit]->y_index_pending = 0; 397430391Skarels 3975*34615Smarc /*---------------------------------------------------------------- 3976*34615Smarc * assign a pointer to the color map write buffer for this QDSS */ 397730391Skarels 397830391Skarels color_buf[unit] = (struct color_buf *) 397930391Skarels (((int)(&color_shared[0] + 512) & ~0x1FF) 398030391Skarels + (COLOR_BUFSIZ * unit)); 398130391Skarels 398230391Skarels color_buf[unit]->status = 0; 398330391Skarels color_buf[unit]->count = 0; 398430391Skarels 398530391Skarels } /* init_shared */ 398630391Skarels 398730391Skarels /********************************************************************* 398830391Skarels * 398930391Skarels * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map 399030391Skarels * 399130391Skarels ********************************************************************** 399230391Skarels * 399330391Skarels * calling convention: 399430391Skarels * 399530391Skarels * setup_dragon(); 399630391Skarels * 399730391Skarels * return: NONE 399830391Skarels * 399930391Skarels ************************/ 400030391Skarels 400130391Skarels setup_dragon(unit) 400230391Skarels u_int unit; 400330391Skarels { 400430391Skarels 400530391Skarels register struct adder *adder; 400630391Skarels register struct dga *dga; 400730391Skarels short *memcsr; 400830391Skarels 400930391Skarels int i; /* general purpose variables */ 401030391Skarels int status; 401130391Skarels 401230391Skarels short top; /* clipping/scrolling boundaries */ 401330391Skarels short bottom; 401430391Skarels short right; 401530391Skarels short left; 401630391Skarels 401730391Skarels short *red; /* color map pointers */ 401830391Skarels short *green; 401930391Skarels short *blue; 402030391Skarels 4021*34615Smarc /*------------------ 4022*34615Smarc * init for setup */ 402330391Skarels 402430391Skarels adder = (struct adder *) qdmap[unit].adder; 402530391Skarels dga = (struct dga *) qdmap[unit].dga; 402630391Skarels memcsr = (short *) qdmap[unit].memcsr; 402730391Skarels 402830391Skarels dga->csr &= ~(DMA_IE | 0x700); /* halt DMA and kill the intrpts */ 402930391Skarels *memcsr = SYNC_ON; /* blank screen and turn off LED's */ 403030391Skarels adder->command = CANCEL; 403130391Skarels 4032*34615Smarc /*---------------------- 4033*34615Smarc * set monitor timing */ 403430391Skarels 403530391Skarels adder->x_scan_count_0 = 0x2800; 403630391Skarels adder->x_scan_count_1 = 0x1020; 403730391Skarels adder->x_scan_count_2 = 0x003A; 403830391Skarels adder->x_scan_count_3 = 0x38F0; 403930391Skarels adder->x_scan_count_4 = 0x6128; 404030391Skarels adder->x_scan_count_5 = 0x093A; 404130391Skarels adder->x_scan_count_6 = 0x313C; 404230391Skarels adder->sync_phase_adj = 0x0100; 404330391Skarels adder->x_scan_conf = 0x00C8; 404430391Skarels 4045*34615Smarc /*--------------------------------------------------------- 4046*34615Smarc * got a bug in secound pass ADDER! lets take care of it */ 404730391Skarels 404830391Skarels /* normally, just use the code in the following bug fix code, but to 404930391Skarels * make repeated demos look pretty, load the registers as if there was 405030391Skarels * no bug and then test to see if we are getting sync */ 405130391Skarels 405230391Skarels adder->y_scan_count_0 = 0x135F; 405330391Skarels adder->y_scan_count_1 = 0x3363; 405430391Skarels adder->y_scan_count_2 = 0x2366; 405530391Skarels adder->y_scan_count_3 = 0x0388; 405630391Skarels 405730391Skarels /* if no sync, do the bug fix code */ 405830391Skarels 405930391Skarels if (wait_status(adder, VSYNC) == BAD) { 406030391Skarels 406130391Skarels /* first load all Y scan registers with very short frame and 406230391Skarels * wait for scroll service. This guarantees at least one SYNC 406330391Skarels * to fix the pass 2 Adder initialization bug (synchronizes 406430391Skarels * XCINCH with DMSEEDH) */ 406530391Skarels 406630391Skarels adder->y_scan_count_0 = 0x01; 406730391Skarels adder->y_scan_count_1 = 0x01; 406830391Skarels adder->y_scan_count_2 = 0x01; 406930391Skarels adder->y_scan_count_3 = 0x01; 407030391Skarels 407130391Skarels wait_status(adder, VSYNC); /* delay at least 1 full frame time */ 407230391Skarels wait_status(adder, VSYNC); 407330391Skarels 407430391Skarels /* now load the REAL sync values (in reverse order just to 407530391Skarels * be safe. */ 407630391Skarels 407730391Skarels adder->y_scan_count_3 = 0x0388; 407830391Skarels adder->y_scan_count_2 = 0x2366; 407930391Skarels adder->y_scan_count_1 = 0x3363; 408030391Skarels adder->y_scan_count_0 = 0x135F; 408130391Skarels } 408230391Skarels 408330391Skarels *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ 408430391Skarels 4085*34615Smarc /*---------------------------- 4086*34615Smarc * zero the index registers */ 408730391Skarels 408830391Skarels adder->x_index_pending = 0; 408930391Skarels adder->y_index_pending = 0; 409030391Skarels adder->x_index_new = 0; 409130391Skarels adder->y_index_new = 0; 409230391Skarels adder->x_index_old = 0; 409330391Skarels adder->y_index_old = 0; 409430391Skarels 409530391Skarels adder->pause = 0; 409630391Skarels 4097*34615Smarc /*---------------------------------------- 4098*34615Smarc * set rasterop mode to normal pen down */ 409930391Skarels 410030391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 410130391Skarels 4102*34615Smarc /*-------------------------------------------------- 4103*34615Smarc * set the rasterop registers to a default values */ 410430391Skarels 410530391Skarels adder->source_1_dx = 1; 410630391Skarels adder->source_1_dy = 1; 410730391Skarels adder->source_1_x = 0; 410830391Skarels adder->source_1_y = 0; 410930391Skarels adder->destination_x = 0; 411030391Skarels adder->destination_y = 0; 411130391Skarels adder->fast_dest_dx = 1; 411230391Skarels adder->fast_dest_dy = 0; 411330391Skarels adder->slow_dest_dx = 0; 411430391Skarels adder->slow_dest_dy = 1; 411530391Skarels adder->error_1 = 0; 411630391Skarels adder->error_2 = 0; 411730391Skarels 4118*34615Smarc /*------------------------ 4119*34615Smarc * scale factor = unity */ 412030391Skarels 412130391Skarels adder->fast_scale = UNITY; 412230391Skarels adder->slow_scale = UNITY; 412330391Skarels 4124*34615Smarc /*------------------------------- 4125*34615Smarc * set the source 2 parameters */ 412630391Skarels 412730391Skarels adder->source_2_x = 0; 412830391Skarels adder->source_2_y = 0; 412930391Skarels adder->source_2_size = 0x0022; 413030391Skarels 4131*34615Smarc /*----------------------------------------------- 4132*34615Smarc * initialize plane addresses for eight vipers */ 413330391Skarels 413430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 413530391Skarels write_ID(adder, PLANE_ADDRESS, 0x0000); 413630391Skarels 413730391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0002); 413830391Skarels write_ID(adder, PLANE_ADDRESS, 0x0001); 413930391Skarels 414030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0004); 414130391Skarels write_ID(adder, PLANE_ADDRESS, 0x0002); 414230391Skarels 414330391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0008); 414430391Skarels write_ID(adder, PLANE_ADDRESS, 0x0003); 414530391Skarels 414630391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0010); 414730391Skarels write_ID(adder, PLANE_ADDRESS, 0x0004); 414830391Skarels 414930391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0020); 415030391Skarels write_ID(adder, PLANE_ADDRESS, 0x0005); 415130391Skarels 415230391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0040); 415330391Skarels write_ID(adder, PLANE_ADDRESS, 0x0006); 415430391Skarels 415530391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0080); 415630391Skarels write_ID(adder, PLANE_ADDRESS, 0x0007); 415730391Skarels 415830391Skarels /* initialize the external registers. */ 415930391Skarels 416030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); 416130391Skarels write_ID(adder, CS_SCROLL_MASK, 0x00FF); 416230391Skarels 416330391Skarels /* initialize resolution mode */ 416430391Skarels 416530391Skarels write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ 416630391Skarels write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ 416730391Skarels 416830391Skarels /* initialize viper registers */ 416930391Skarels 417030391Skarels write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); 417130391Skarels write_ID(adder, SCROLL_FILL, 0x0000); 417230391Skarels 4173*34615Smarc /*---------------------------------------------------- 4174*34615Smarc * set clipping and scrolling limits to full screen */ 417530391Skarels 417630391Skarels for ( i = 1000, adder->status = 0 417730391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 417830391Skarels ; --i); 417930391Skarels 418030391Skarels if (i == 0) 4181*34615Smarc printf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 418230391Skarels 418330391Skarels top = 0; 418430391Skarels bottom = 2048; 418530391Skarels left = 0; 418630391Skarels right = 1024; 418730391Skarels 418830391Skarels adder->x_clip_min = left; 418930391Skarels adder->x_clip_max = right; 419030391Skarels adder->y_clip_min = top; 419130391Skarels adder->y_clip_max = bottom; 419230391Skarels 419330391Skarels adder->scroll_x_min = left; 419430391Skarels adder->scroll_x_max = right; 419530391Skarels adder->scroll_y_min = top; 419630391Skarels adder->scroll_y_max = bottom; 419730391Skarels 419830391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 419930391Skarels wait_status(adder, VSYNC); 420030391Skarels 420130391Skarels adder->x_index_pending = left; 420230391Skarels adder->y_index_pending = top; 420330391Skarels adder->x_index_new = left; 420430391Skarels adder->y_index_new = top; 420530391Skarels adder->x_index_old = left; 420630391Skarels adder->y_index_old = top; 420730391Skarels 420830391Skarels for ( i = 1000, adder->status = 0 420930391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 421030391Skarels ; --i); 421130391Skarels 421230391Skarels if (i == 0) 4213*34615Smarc printf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 421430391Skarels 421530391Skarels write_ID(adder, LEFT_SCROLL_MASK, 0x0000); 421630391Skarels write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); 421730391Skarels 4218*34615Smarc /*------------------------------------------------------------ 4219*34615Smarc * set source and the mask register to all ones (ie: white) */ 422030391Skarels 422130391Skarels write_ID(adder, SOURCE, 0xFFFF); 422230391Skarels write_ID(adder, MASK_1, 0xFFFF); 422330391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 422430391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 422530391Skarels 4226*34615Smarc /*-------------------------------------------------------------- 4227*34615Smarc * initialize Operand Control Register banks for fill command */ 422830391Skarels 422930391Skarels write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); 423030391Skarels write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); 423130391Skarels write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 423230391Skarels 423330391Skarels write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); 423430391Skarels write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); 423530391Skarels write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 423630391Skarels 4237*34615Smarc /*------------------------------------------------------------------ 4238*34615Smarc * init Logic Unit Function registers, (these are just common values, 423930391Skarels * and may be changed as required). */ 424030391Skarels 424130391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 424230391Skarels write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); 424330391Skarels write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); 424430391Skarels write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); 424530391Skarels 4246*34615Smarc /*---------------------------------------- 4247*34615Smarc * load the color map for black & white */ 424830391Skarels 424930391Skarels for ( i = 0, adder->status = 0 425030391Skarels ; i < 10000 && !((status = adder->status) & VSYNC) 425130391Skarels ; ++i); 425230391Skarels 425330391Skarels if (i == 0) 4254*34615Smarc printf("\nqd%d: setup_dragon: timeout on VSYNC", unit); 425530391Skarels 425630391Skarels red = (short *) qdmap[unit].red; 425730391Skarels green = (short *) qdmap[unit].green; 425830391Skarels blue = (short *) qdmap[unit].blue; 425930391Skarels 426030391Skarels *red++ = 0x00; /* black */ 426130391Skarels *green++ = 0x00; 426230391Skarels *blue++ = 0x00; 426330391Skarels 426430391Skarels *red-- = 0xFF; /* white */ 426530391Skarels *green-- = 0xFF; 426630391Skarels *blue-- = 0xFF; 426730391Skarels 426830391Skarels /*---------------------------------- 426930391Skarels * set color map for mouse cursor */ 427030391Skarels 427130391Skarels red += 254; 427230391Skarels green += 254; 427330391Skarels blue += 254; 427430391Skarels 427530391Skarels *red++ = 0x00; /* black */ 427630391Skarels *green++ = 0x00; 427730391Skarels *blue++ = 0x00; 427830391Skarels 427930391Skarels *red = 0xFF; /* white */ 428030391Skarels *green = 0xFF; 428130391Skarels *blue = 0xFF; 428230391Skarels 428330391Skarels return(0); 428430391Skarels 428530391Skarels } /* setup_dragon */ 428630391Skarels 428730391Skarels /****************************************************************** 428830391Skarels * 428930391Skarels * setup_input()... init the DUART and set defaults in input 429030391Skarels * devices 429130391Skarels * 429230391Skarels ******************************************************************* 429330391Skarels * 429430391Skarels * calling convention: 429530391Skarels * 429630391Skarels * setup_input(unit); 429730391Skarels * 429830391Skarels * where: unit - is the QDSS unit number to be setup 429930391Skarels * 430030391Skarels *********/ 430130391Skarels 430230391Skarels setup_input(unit) 430330391Skarels u_int unit; 430430391Skarels { 430530391Skarels register struct duart *duart; /* DUART register structure pointer */ 430630391Skarels register int i; /* scratch variable */ 430730391Skarels register int bits; 430830391Skarels 430930391Skarels char id_byte; 431030391Skarels short status; 431130391Skarels 4312*34615Smarc /*--------------- 4313*34615Smarc * init stuff */ 431430391Skarels 431530391Skarels duart = (struct duart *) qdmap[unit].duart; 431630391Skarels duart->imask = 0; 431730391Skarels 4318*34615Smarc /*--------------------------------------------- 4319*34615Smarc * setup the DUART for kbd & pointing device */ 432030391Skarels 432130391Skarels duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ 432230391Skarels duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ 432330391Skarels /* no RTS control,char error mode */ 432430391Skarels duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ 432530391Skarels /* no RTS control,no echo or loop */ 432630391Skarels duart->cmdB = RESET_M; /* reset mode reg pntr for host */ 432730391Skarels duart->modeB = 0x07; /* 8 bits, odd parity, rcv IE.. */ 432830391Skarels /* ..no RTS cntrl, char error mode */ 432930391Skarels duart->modeB = 0x07; /* 1 stop bit,CTS does not IE XMT */ 433030391Skarels /* no RTS control,no echo or loop */ 433130391Skarels 433230391Skarels duart->auxctl = 0x00; /* baud rate set 1 */ 433330391Skarels 433430391Skarels duart->clkselA = 0x99; /* 4800 baud for kbd */ 433530391Skarels duart->clkselB = 0x99; /* 4800 baud for mouse */ 433630391Skarels 433730391Skarels /* reset everything for keyboard */ 433830391Skarels 433930391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 434030391Skarels duart->cmdA = bits; 434130391Skarels 434230391Skarels /* reset everything for host */ 434330391Skarels 434430391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 434530391Skarels duart->cmdB = bits; 434630391Skarels 434730391Skarels duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ 434830391Skarels duart->cmdB = EN_RCV | EN_XMT; /* enbl xmt & rcv for pointer device */ 434930391Skarels 4350*34615Smarc /*-------------------------------------------- 4351*34615Smarc * init keyboard defaults (DUART channel A) */ 435230391Skarels 435330391Skarels for (i = 500; i > 0; --i) { 435430391Skarels if ((status = duart->statusA) & XMT_RDY) { 435530391Skarels duart->dataA = LK_DEFAULTS; 435630391Skarels break; 435730391Skarels } 435830391Skarels } 435930391Skarels 436030391Skarels for (i = 100000; i > 0; --i) { 436130391Skarels if ((status = duart->statusA) & RCV_RDY) { 436230391Skarels break; 436330391Skarels } 436430391Skarels } 436530391Skarels 436630391Skarels status = duart->dataA; /* flush the ACK */ 436730391Skarels 4368*34615Smarc /*-------------------------------- 4369*34615Smarc * identify the pointing device */ 437030391Skarels 437130391Skarels for (i = 500; i > 0; --i) { 437230391Skarels if ((status = duart->statusB) & XMT_RDY) { 437330391Skarels duart->dataB = SELF_TEST; 437430391Skarels break; 437530391Skarels } 437630391Skarels } 437730391Skarels 437830391Skarels /*----------------------------------------- 437930391Skarels * wait for 1st byte of self test report */ 438030391Skarels 438130391Skarels for (i = 100000; i > 0; --i) { 438230391Skarels if ((status = duart->statusB) & RCV_RDY) { 438330391Skarels break; 438430391Skarels } 438530391Skarels } 438630391Skarels 438730391Skarels if (i == 0) { 4388*34615Smarc printf("\nqd[%d]: setup_input: timeout on 1st byte of self test",unit); 438930391Skarels goto OUT; 439030391Skarels } 439130391Skarels 439230391Skarels status = duart->dataB; 439330391Skarels 439430391Skarels /*----------------------------------------- 439530391Skarels * wait for ID byte of self test report */ 439630391Skarels 439730391Skarels for (i = 100000; i > 0; --i) { 439830391Skarels if ((status = duart->statusB) & RCV_RDY) { 439930391Skarels break; 440030391Skarels } 440130391Skarels } 440230391Skarels 440330391Skarels if (i == 0) { 4404*34615Smarc printf("\nqd[%d]: setup_input: timeout on 2nd byte of self test", unit); 440530391Skarels goto OUT; 440630391Skarels } 440730391Skarels 440830391Skarels id_byte = duart->dataB; 440930391Skarels 441030391Skarels /*------------------------------------ 441130391Skarels * wait for other bytes to come in */ 441230391Skarels 441330391Skarels for (i = 100000; i > 0; --i) { 441430391Skarels if ((status = duart->statusB) & RCV_RDY) { 441530391Skarels status = duart->dataB; 441630391Skarels break; 441730391Skarels } 441830391Skarels } 441930391Skarels 442030391Skarels if (i == 0) { 4421*34615Smarc printf("\nqd[%d]: setup_input: timeout on 3rd byte of self test", unit); 442230391Skarels goto OUT; 442330391Skarels } 442430391Skarels 442530391Skarels for (i = 100000; i > 0; --i) { 442630391Skarels if ((status = duart->statusB) & RCV_RDY) { 442730391Skarels status = duart->dataB; 442830391Skarels break; 442930391Skarels } 443030391Skarels } 443130391Skarels 443230391Skarels if (i == 0) { 4433*34615Smarc printf("\nqd[%d]: setup_input: timeout on 4th byte of self test\n", unit); 443430391Skarels goto OUT; 443530391Skarels } 443630391Skarels 443730391Skarels /*---------------------------------------------- 443830391Skarels * flag pointing device type and set defaults */ 443930391Skarels 444030391Skarels for (i=100000; i>0; --i); 444130391Skarels 444230391Skarels if ((id_byte & 0x0F) != TABLET_ID) { 444330391Skarels 444430391Skarels qdflags[unit].pntr_id = MOUSE_ID; 444530391Skarels 444630391Skarels for (i = 500; i > 0; --i) { 444730391Skarels if ((status = duart->statusB) & XMT_RDY) { 444830391Skarels duart->dataB = INC_STREAM_MODE; 444930391Skarels break; 445030391Skarels } 445130391Skarels } 445230391Skarels } else { 445330391Skarels 445430391Skarels qdflags[unit].pntr_id = TABLET_ID; 445530391Skarels 445630391Skarels for (i = 500; i > 0; --i) { 445730391Skarels if ((status = duart->statusB) & XMT_RDY) { 445830391Skarels duart->dataB = T_STREAM; 445930391Skarels break; 446030391Skarels } 446130391Skarels } 446230391Skarels } 446330391Skarels 4464*34615Smarc /*-------- 4465*34615Smarc * exit */ 446630391Skarels 446730391Skarels OUT: 446830391Skarels duart->imask = qdflags[unit].duart_imask; 446930391Skarels return(0); 447030391Skarels 447130391Skarels } /* setup_input */ 447230391Skarels 447330391Skarels /********************************************************************** 447430391Skarels * 447530391Skarels * wait_status()... delay for at least one display frame time 447630391Skarels * 447730391Skarels *********************************************************************** 447830391Skarels * 447930391Skarels * calling convention: 448030391Skarels * 448130391Skarels * wait_status(adder, mask); 448230391Skarels * struct *adder adder; 448330391Skarels * int mask; 448430391Skarels * 448530391Skarels * return: BAD means that we timed out without ever seeing the 448630391Skarels * vertical sync status bit 448730391Skarels * GOOD otherwise 448830391Skarels * 448930391Skarels **************/ 449030391Skarels 449130391Skarels wait_status(adder, mask) 449230391Skarels register struct adder *adder; 449330391Skarels register int mask; 449430391Skarels { 449530391Skarels register short status; 449630391Skarels int i; 449730391Skarels 449830391Skarels for ( i = 10000, adder->status = 0 449930391Skarels ; i > 0 && !((status = adder->status) & mask) 450030391Skarels ; --i); 450130391Skarels 450230391Skarels if (i == 0) { 4503*34615Smarc printf("\nwait_status: timeout polling for 0x%x in adder->status", mask); 450430391Skarels return(BAD); 450530391Skarels } 450630391Skarels 450730391Skarels return(GOOD); 450830391Skarels 450930391Skarels } /* wait_status */ 451030391Skarels 451130391Skarels /********************************************************************** 451230391Skarels * 451330391Skarels * write_ID()... write out onto the ID bus 451430391Skarels * 451530391Skarels *********************************************************************** 451630391Skarels * 451730391Skarels * calling convention: 451830391Skarels * 451930391Skarels * struct *adder adder; ;pntr to ADDER structure 452030391Skarels * short adrs; ;VIPER address 452130391Skarels * short data; ;data to be written 452230391Skarels * write_ID(adder); 452330391Skarels * 452430391Skarels * return: BAD means that we timed out waiting for status bits 452530391Skarels * VIPER-access-specific status bits 452630391Skarels * GOOD otherwise 452730391Skarels * 452830391Skarels **************/ 452930391Skarels 453030391Skarels write_ID(adder, adrs, data) 453130391Skarels register struct adder *adder; 453230391Skarels register short adrs; 453330391Skarels register short data; 453430391Skarels { 453530391Skarels int i; 453630391Skarels short status; 453730391Skarels 4538*34615Smarc for ( i = 100000, adder->status = 0 4539*34615Smarc ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 4540*34615Smarc ; --i); 454130391Skarels 454230391Skarels if (i == 0) 454330391Skarels goto ERR; 454430391Skarels 4545*34615Smarc for ( i = 100000, adder->status = 0 4546*34615Smarc ; i > 0 && !((status = adder->status) & TX_READY) 4547*34615Smarc ; --i); 454830391Skarels 454930391Skarels if (i > 0) { 455030391Skarels adder->id_data = data; 455130391Skarels adder->command = ID_LOAD | adrs; 455230391Skarels return(GOOD); 455330391Skarels } 455430391Skarels 455530391Skarels ERR: 4556*34615Smarc printf("\nwrite_ID: timeout trying to write to VIPER"); 455730391Skarels return(BAD); 455830391Skarels 455930391Skarels } /* write_ID */ 4560*34615Smarc 456134511Smarc #endif 4562