130391Skarels #ifndef lint 2*32012Smarc static char *sccsid = "@(#)qd.c 1.2 Berkeley 08/07/87"; 3*32012Smarc static char *osccsid = "@(#)qd.c 1.40 ULTRIX 10/2/86"; 430391Skarels #endif lint 530391Skarels 630391Skarels /************************************************************************ 730391Skarels * * 830391Skarels * Copyright (c) 1985, 1986 by * 930391Skarels * Digital Equipment Corporation, Maynard, MA * 1030391Skarels * All rights reserved. * 1130391Skarels * * 1230391Skarels * This software is furnished under a license and may be used and * 1330391Skarels * copied only in accordance with the terms of such license and * 1430391Skarels * with the inclusion of the above copyright notice. This * 1530391Skarels * software or any other copies thereof may not be provided or * 1630391Skarels * otherwise made available to any other person. No title to and * 1730391Skarels * ownership of the software is hereby transferred. * 1830391Skarels * * 1930391Skarels * The information in this software is subject to change without * 2030391Skarels * notice and should not be construed as a commitment by Digital * 2130391Skarels * Equipment Corporation. * 2230391Skarels * * 2330391Skarels * Digital assumes no responsibility for the use or reliability * 2430391Skarels * of its software on equipment which is not supplied by Digital. * 2530391Skarels * * 2630391Skarels *************************************************************************/ 2730391Skarels 28*32012Smarc 2930391Skarels /* 3030391Skarels * qd.c 3130391Skarels * 3230391Skarels * Modification history 3330391Skarels * 3430391Skarels * QDSS workstation driver 3530391Skarels * 36*32012Smarc * Aug 1987 - marc@ucbvax.berkeley.edu 37*32012Smarc * 38*32012Smarc * Modify for 4.3bsd with Mikes help. Add cursor motion support 39*32012Smarc * in glass tty. Work around glass tty output bug (which causes 40*32012Smarc * screen to freeze). Reformat as many comments as patience would 41*32012Smarc * allow. Use 4.3 console redirect (TIOCCONS) instead of smashing 42*32012Smarc * cdevsw. Supporting changes are in locore.s (for map), 43*32012Smarc * machdep.c, and conf.c. Note that the major number for qd 44*32012Smarc * is different from ultrix: on 4.3bsd its 41, and on 45*32012Smarc * ultrix its 42. 46*32012Smarc * 4730391Skarels * 26-Aug-86 - rsp (Ricky Palmer) 4830391Skarels * 4930391Skarels * Cleaned up devioctl code to (1) zero out devget structure 5030391Skarels * upon entry and (2) use strlen instead of fixed storage 5130391Skarels * for bcopy's. 5230391Skarels * 5330391Skarels * 21-Jul-86 - Ram Rao 5430391Skarels * allowed cursor rectangle to hang (partially) off the 5530391Skarels * top and left of screen 5630391Skarels * 5730391Skarels * 11-Jul-86 - ricky palmer 5830391Skarels * 5930391Skarels * Added adpt and nexus fields to DEVIOCGET code. 6030391Skarels * 6130391Skarels * 02-July-86 - Brian Stevens 6230391Skarels * 6330391Skarels * added support for console writing to second QDSS display 6430391Skarels * 6530391Skarels * 20-May-86 - ricky palmer 6630391Skarels * 6730391Skarels * Added new DEVIOCGET ioctl request code. V2.0 6830391Skarels * 6930391Skarels * 16-Apr-86 -- darrell 7030391Skarels * badaddr is now called via the macro BADADDR 7130391Skarels * 7230391Skarels * 14-Apr-86 -- afd 7330391Skarels * Changed UMEMmap to QMEMmap and umem to qmem. 7430391Skarels * 7530391Skarels * v_console() is now refered to as v_consputc, and there is a 7630391Skarels * corresponding v_consgetc() (defined in /sys/vax/conf.c). 7730391Skarels * 7830391Skarels * Added "qdgetc()" routine for console read. Needed to read 7930391Skarels * user's answer to the "root device?" prompt with a generic kernel. 8030391Skarels * 8130391Skarels * 19-Mar-86 -- pmk 8230391Skarels * Change DELAY to 20000, because microdelay now in real microsec. 8330391Skarels * 8430391Skarels * 18-mar-86 -- jaw br/cvec changed to NOT use registers. 8530391Skarels * 8630391Skarels * 11 mar 86 darrell replaced percpu with cpusw, and removed all but 8730391Skarels * one global reference 8830391Skarels * 19 feb 86 bstevens no report of motion event on puck/stylus button action 8930391Skarels * 18 feb 86 bstevens put in cursor box support for tablets 9030391Skarels * 18-Mar-86 -- jaw add routines to cpu switch for nexus/unibus addreses 9130391Skarels * also got rid of some globals like nexnum. 9230391Skarels * ka8800 cleanup. 9330391Skarels * 06 dec 85 longo added LK-201 error reporting for graphics device ops 9430391Skarels * 03 dec 85 longo made qddint() clear active bit on error 9530391Skarels * 02 dec 85 longo fixed up some crocks in the error messages 9630391Skarels * 25 nov 85 longo added error handling to DMA ISR and single user locking 9730391Skarels * 19 nov 85 longo eliminated "set_defaults()" by breaking out sub-calls. 9830391Skarels * Changed init_shared to do real init of scroll struct 9930391Skarels * 12 nov 85 longo fixed bug in open that broke alternate console re-direct 10030391Skarels * 11 nov 85 longo changed "_vs_eventqueue" references to "qdinput" 10130391Skarels * 08 nov 85 longo improved select service for read/write select wakeup. 10230391Skarels * Also set ISR's to ipl4 to allow the interval timer in. 10330391Skarels * 04 nov 85 longo fixed bugs in mouse button reporting and dma request stuff 10430391Skarels * 30 oct 85 longo DMA to/from user space is in place 10530391Skarels * 14 oct 85 longo added kernel msg redirect and QD_RDCURSOR ioctl 10630391Skarels * 03 oct 85 longo added support for multiple QDSS's 10730391Skarels * 02 oct 85 longo added color map loading services in qdioctl() & qdaint() 10830391Skarels * 30 sep 85 longo added DMA interrupt services 10930391Skarels * 18 sep 85 longo added scroll services to "qdaint()" adder intrpt service 11030391Skarels * and put in supporting ioctl's 11130391Skarels * 04 sep 85 longo initial implementation of DMA is working 11230391Skarels * 17 aug 85 longo added support for the QDSS to be system console 11330391Skarels * 05 aug 85 longo now using qfont (QVSS & QDSS) as linked object 11430391Skarels * 12 jun 85 longo added mouse event loading to "qdiint()" 11530391Skarels * 31 may 85 longo put live interrupts into the probe() routine 11630391Skarels * 30 may 85 longo event queue shared memory implementation is now alive 11730391Skarels * 29 may 85 longo LK-201 input is now interrupt driven 11830391Skarels * 25 apr 85 longo MAPDEVICE works 11930391Skarels * 14 mar 85 longo created 12030391Skarels * 12130391Skarels * todo: fix rlogin bug in console stuff 12230391Skarels * check error return from strategy routine 12330391Skarels * verify TOY time stuff (what format?) 12430391Skarels * look at system based macro implementation of VTOP 12530391Skarels * 12630391Skarels */ 12730391Skarels 128*32012Smarc #define mprintf printf 129*32012Smarc #include "qd.h" /* # of QDSS's the system is configured for */ 13030391Skarels 131*32012Smarc #include "../vax/pte.h" /* page table values */ 132*32012Smarc #include "../vax/mtpr.h" /* VAX register access stuff */ 13330391Skarels 134*32012Smarc #include "../h/param.h" /* general system params & macros */ 135*32012Smarc #include "../h/conf.h" /* "linesw" tty driver dispatch */ 136*32012Smarc #include "../h/dir.h" /* for directory handling */ 137*32012Smarc #include "../h/user.h" /* user structure (what else?) */ 138*32012Smarc #include "../ultrix/qdioctl.h" /* ioctl call values */ 139*32012Smarc #include "../h/tty.h" 140*32012Smarc #include "../h/map.h" /* resource allocation map struct */ 141*32012Smarc #include "../h/buf.h" /* buf structs */ 142*32012Smarc #include "../h/vm.h" /* includes 'vm' header files */ 143*32012Smarc #include "../h/clist.h" /* char list handling structs */ 144*32012Smarc #include "../h/file.h" /* file I/O definitions */ 145*32012Smarc #include "../h/uio.h" /* write/read call structs */ 146*32012Smarc #include "../h/kernel.h" /* clock handling structs */ 147*32012Smarc #include "../vax/cpu.h" /* per cpu (pcpu) struct */ 148*32012Smarc 149*32012Smarc #include "../vaxuba/ubareg.h" /* uba & 'qba' register structs */ 150*32012Smarc #include "../vaxuba/ubavar.h" /* uba structs & uba map externs */ 151*32012Smarc #include "../h/syslog.h" 152*32012Smarc 153*32012Smarc #include "../ultrix/qduser.h" /* definitions shared with my client */ 154*32012Smarc #include "../ultrix/qdreg.h" /* QDSS device register structures */ 155*32012Smarc 156*32012Smarc /* 157*32012Smarc * QDSS driver status flags for tracking operational state 158*32012Smarc */ 159*32012Smarc 160*32012Smarc struct qdflags { 161*32012Smarc 162*32012Smarc u_int inuse; /* which minor dev's are in use now */ 163*32012Smarc u_int config; /* I/O page register content */ 164*32012Smarc u_int mapped; /* user mapping status word */ 165*32012Smarc u_int kernel_loop; /* if kernel console is redirected */ 166*32012Smarc u_int user_dma; /* DMA from user space in progress */ 167*32012Smarc u_short pntr_id; /* type code of pointing device */ 168*32012Smarc u_short duart_imask; /* shadowing for duart intrpt mask reg */ 169*32012Smarc u_short adder_ie; /* shadowing for adder intrpt enbl reg */ 170*32012Smarc u_short curs_acc; /* cursor acceleration factor */ 171*32012Smarc u_short curs_thr; /* cursor acceleration threshold level */ 172*32012Smarc u_short tab_res; /* tablet resolution factor */ 173*32012Smarc u_short selmask; /* mask for active qd select entries */ 174*32012Smarc }; 175*32012Smarc 176*32012Smarc /* bit definitions for "inuse" entry */ 177*32012Smarc 178*32012Smarc #define CONS_DEV 0x01 179*32012Smarc #define ALTCONS_DEV 0x02 180*32012Smarc #define GRAPHIC_DEV 0x04 181*32012Smarc 182*32012Smarc /* bit definitions for 'mapped' member of flag structure */ 183*32012Smarc 184*32012Smarc #define MAPDEV 0x01 /* hardware is mapped */ 185*32012Smarc #define MAPDMA 0x02 /* DMA buffer mapped */ 186*32012Smarc #define MAPEQ 0x04 /* event queue buffer mapped */ 187*32012Smarc #define MAPSCR 0x08 /* scroll param area mapped */ 188*32012Smarc #define MAPCOLOR 0x10 /* color map writing buffer mapped */ 189*32012Smarc 190*32012Smarc /* bit definitions for 'selmask' member of qdflag structure */ 191*32012Smarc 192*32012Smarc #define SEL_READ 0x01 /* read select is active */ 193*32012Smarc #define SEL_WRITE 0x02 /* write select is active */ 194*32012Smarc 195*32012Smarc /* 196*32012Smarc * constants used in shared memory operations 197*32012Smarc */ 198*32012Smarc 199*32012Smarc #define EVENT_BUFSIZE 1024 /* # of bytes per device's event buffer */ 200*32012Smarc 201*32012Smarc #define MAXEVENTS ( (EVENT_BUFSIZE - sizeof(struct qdinput)) \ 202*32012Smarc / sizeof(struct _vs_event) ) 203*32012Smarc 204*32012Smarc #define DMA_BUFSIZ (1024 * 3) 205*32012Smarc 206*32012Smarc #define COLOR_BUFSIZ ((sizeof(struct color_buf) + 512) & ~0x01FF) 207*32012Smarc 208*32012Smarc 209*32012Smarc 210*32012Smarc /* 211*32012Smarc * reference to an array of "uba_device" structures built by the auto 212*32012Smarc * configuration program. The uba_device structure decribes the device 213*32012Smarc * sufficiently for the driver to talk to it. The auto configuration code 214*32012Smarc * fills in the uba_device structures (located in ioconf.c) from user 215*32012Smarc * maintained info. 216*32012Smarc */ 217*32012Smarc 218*32012Smarc struct uba_device *qdinfo[NQD]; /* array of pntrs to each QDSS's */ 219*32012Smarc /* uba structures */ 220*32012Smarc struct tty qd_tty[NQD*4]; /* teletype structures for each.. */ 221*32012Smarc /* ..possible minor device */ 222*32012Smarc 223*32012Smarc struct qd_softc qd_softc[NQD]; 224*32012Smarc 225*32012Smarc /* 226*32012Smarc * static storage used by multiple functions in this code 227*32012Smarc */ 228*32012Smarc 229*32012Smarc int Qbus_unmap[NQD]; /* Qbus mapper release code */ 230*32012Smarc struct qdflags qdflags[NQD]; /* QDSS device status flags */ 231*32012Smarc struct qdmap qdmap[NQD]; /* QDSS register map structure */ 232*32012Smarc caddr_t qdbase[NQD]; /* base address of each QDSS unit */ 233*32012Smarc struct buf qdbuf[NQD]; /* buf structs used by strategy */ 234*32012Smarc char one_only[NQD]; /* lock for single process access */ 235*32012Smarc 236*32012Smarc /* 237*32012Smarc * The array "event_shared[]" is made up of a number of event queue buffers 238*32012Smarc * equal to the number of QDSS's configured into the running kernel (NQD). 239*32012Smarc * Each event queue buffer begins with an event queue header (struct qdinput) 240*32012Smarc * followed by a group of event queue entries (struct _vs_event). The array 241*32012Smarc * "*eq_header[]" is an array of pointers to the start of each event queue 242*32012Smarc * buffer in "event_shared[]". 243*32012Smarc */ 244*32012Smarc 245*32012Smarc #define EQSIZE ((EVENT_BUFSIZE * NQD) + 512) 246*32012Smarc 247*32012Smarc char event_shared[EQSIZE]; /* reserve space for event bufs */ 248*32012Smarc struct qdinput *eq_header[NQD]; /* event queue header pntrs */ 249*32012Smarc 250*32012Smarc /* 251*32012Smarc * This allocation method reserves enough memory pages for NQD shared DMA I/O 252*32012Smarc * buffers. Each buffer must consume an integral number of memory pages to 253*32012Smarc * guarantee that a following buffer will begin on a page boundary. Also, 254*32012Smarc * enough space is allocated so that the FIRST I/O buffer can start at the 255*32012Smarc * 1st page boundary after "&DMA_shared". Page boundaries are used so that 256*32012Smarc * memory protections can be turned on/off for individual buffers. 257*32012Smarc */ 258*32012Smarc 259*32012Smarc #define IOBUFSIZE ((DMA_BUFSIZ * NQD) + 512) 260*32012Smarc 261*32012Smarc char DMA_shared[IOBUFSIZE]; /* reserve I/O buffer space */ 262*32012Smarc struct DMAreq_header *DMAheader[NQD]; /* DMA buffer header pntrs */ 263*32012Smarc 264*32012Smarc /* 265*32012Smarc * The driver assists a client in scroll operations by loading dragon 266*32012Smarc * registers from an interrupt service routine. The loading is done using 267*32012Smarc * parameters found in memory shrade between the driver and it's client. 268*32012Smarc * The scroll parameter structures are ALL loacted in the same memory page 269*32012Smarc * for reasons of memory economy. 270*32012Smarc */ 271*32012Smarc 272*32012Smarc char scroll_shared[2 * 512]; /* reserve space for scroll structs */ 273*32012Smarc struct scroll *scroll[NQD]; /* pointers to scroll structures */ 274*32012Smarc 275*32012Smarc /* 276*32012Smarc * the driver is programmable to provide the user with color map write 277*32012Smarc * services at VSYNC interrupt time. At interrupt time the driver loads 278*32012Smarc * the color map with any user-requested load data found in shared memory 279*32012Smarc */ 280*32012Smarc 281*32012Smarc #define COLOR_SHARED ((COLOR_BUFSIZ * NQD) + 512) 282*32012Smarc 283*32012Smarc char color_shared[COLOR_SHARED]; /* reserve space: color bufs */ 284*32012Smarc struct color_buf *color_buf[NQD]; /* pointers to color bufs */ 285*32012Smarc 286*32012Smarc /* 287*32012Smarc * mouse input event structures 288*32012Smarc */ 289*32012Smarc 290*32012Smarc struct mouse_report last_rep[NQD]; 291*32012Smarc struct mouse_report current_rep[NQD]; 292*32012Smarc 293*32012Smarc /* 294*32012Smarc * input event "select" use 295*32012Smarc */ 296*32012Smarc 297*32012Smarc struct proc *rsel[NQD]; /* process waiting for select */ 298*32012Smarc 299*32012Smarc /* 300*32012Smarc * console cursor structure 301*32012Smarc */ 302*32012Smarc 303*32012Smarc struct _vs_cursor cursor[NQD]; 304*32012Smarc 305*32012Smarc 306*32012Smarc 307*32012Smarc int nNQD = NQD; 308*32012Smarc 309*32012Smarc int DMAbuf_size = DMA_BUFSIZ; 310*32012Smarc 311*32012Smarc 312*32012Smarc /* 313*32012Smarc * macro to get system time. Used to time stamp event queue entries 314*32012Smarc */ 315*32012Smarc 31630391Skarels #define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000)) 31730391Skarels 318*32012Smarc /* 31930391Skarels * the "ioconf.c" program, built and used by auto config, externally refers 320*32012Smarc * to definitions below. 321*32012Smarc */ 32230391Skarels 323*32012Smarc int qdprobe(); 324*32012Smarc int qdattach(); 325*32012Smarc int qddint(); /* DMA gate array intrpt service */ 326*32012Smarc int qdaint(); /* Dragon ADDER intrpt service */ 327*32012Smarc int qdiint(); 32830391Skarels 329*32012Smarc u_short qdstd[] = { 0 }; 33030391Skarels 331*32012Smarc struct uba_driver qddriver = { /* externally referenced: ioconf.c */ 33230391Skarels 333*32012Smarc qdprobe, /* device probe entry */ 334*32012Smarc 0, /* no slave device */ 335*32012Smarc qdattach, /* device attach entry */ 336*32012Smarc 0, /* no "fill csr/ba to start" */ 337*32012Smarc qdstd, /* device addresses */ 338*32012Smarc "qd", /* device name string */ 339*32012Smarc qdinfo /* ptr to QDSS's uba_device struct */ 340*32012Smarc }; 34130391Skarels 342*32012Smarc extern char qvmem[][128*NBPG]; 343*32012Smarc extern struct pte QVmap[][128]; 344*32012Smarc 345*32012Smarc /* 346*32012Smarc * v_putc is used to redirect the console cnputc to the virtual console 347*32012Smarc * vputc. consops is used to direct the console device to the qvss console. 348*32012Smarc */ 349*32012Smarc extern (*v_putc)(); 350*32012Smarc extern struct cdevsw *consops; 351*32012Smarc 352*32012Smarc /* 35330391Skarels * general defines */ 35430391Skarels 35530391Skarels #define QDPRIOR (PZERO-1) /* must be negative */ 35630391Skarels 35730391Skarels #define FALSE 0 35830391Skarels #define TRUE ~FALSE 35930391Skarels 36030391Skarels #define BAD -1 36130391Skarels #define GOOD 0 36230391Skarels 363*32012Smarc /* 364*32012Smarc * Macro to create a system virtual page number from system virtual adrs. 365*32012Smarc */ 36630391Skarels 367*32012Smarc #define VTOP(x) (((int)x & ~0xC0000000) >> PGSHIFT) 36830391Skarels 369*32012Smarc /* 370*32012Smarc * QDSS register address offsets from start of QDSS address space 371*32012Smarc */ 37230391Skarels 37330391Skarels #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ 37430391Skarels 37530391Skarels #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ 37630391Skarels #define TMPSTART 0x8000 /* offset of template RAM from base adrs */ 37730391Skarels 37830391Skarels #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ 37930391Skarels #define REGSTART 0xC000 /* offset of reg pages from base adrs */ 38030391Skarels 38130391Skarels #define ADDER (REGSTART+0x000) 38230391Skarels #define DGA (REGSTART+0x200) 38330391Skarels #define DUART (REGSTART+0x400) 38430391Skarels #define MEMCSR (REGSTART+0x800) 38530391Skarels 38630391Skarels #define CLRSIZE (3 * 512) /* color map size */ 38730391Skarels #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ 38830391Skarels /* 0x0C00 really */ 38930391Skarels #define RED (CLRSTART+0x000) 39030391Skarels #define BLUE (CLRSTART+0x200) 39130391Skarels #define GREEN (CLRSTART+0x400) 39230391Skarels 393*32012Smarc /* 394*32012Smarc * Values used in mapping QDSS hardware into the Q memory space. 395*32012Smarc */ 39630391Skarels 39730391Skarels #define CHUNK (64 * 1024) 398*32012Smarc #define QMEMSIZE (1024 * 1024 * 4) 39930391Skarels 400*32012Smarc /* 40130391Skarels * QDSS minor device numbers. The *real* minor device numbers are in 40230391Skarels * the bottom two bits of the major/minor device spec. Bits 2 and up are 403*32012Smarc * used to specify the QDSS device number (ie: which one?) 404*32012Smarc */ 40530391Skarels 406*32012Smarc #define QDSSMAJOR 41 /* QDSS major device number */ 40730391Skarels 40830391Skarels #define CONS 0 40930391Skarels #define ALTCONS 1 41030391Skarels #define GRAPHIC 2 41130391Skarels 412*32012Smarc /* 413*32012Smarc * console cursor bitmap (block cursor type) 414*32012Smarc */ 41530391Skarels 41630391Skarels short cons_cursor[32] = { /* white block cursor */ 41730391Skarels 41830391Skarels /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 41930391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 42030391Skarels /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 42130391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 42230391Skarels 42330391Skarels }; 42430391Skarels 425*32012Smarc /* 426*32012Smarc * constants used in font operations 427*32012Smarc */ 42830391Skarels 42930391Skarels #define CHARS 95 /* # of chars in the font */ 43030391Skarels #define CHAR_HEIGHT 15 /* char height in pixels */ 43130391Skarels #define CHAR_WIDTH 8 /* char width in pixels*/ 43230391Skarels #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ 43330391Skarels #define ROWS CHAR_HEIGHT 43430391Skarels 43530391Skarels 43630391Skarels #define FONT_X 0 /* font's off screen adrs */ 43730391Skarels #define FONT_Y (2048 - CHAR_HEIGHT) 43830391Skarels /* 43930391Skarels #define FONT_Y 200 44030391Skarels */ 44130391Skarels 442*32012Smarc extern char q_font[]; /* reference font object code */ 44330391Skarels 444*32012Smarc extern char q_key[]; /* reference key xlation tables */ 445*32012Smarc extern char q_shift_key[]; 446*32012Smarc extern char *q_special[]; 44730391Skarels 448*32012Smarc /* 449*32012Smarc * definitions for cursor acceleration reporting 450*32012Smarc */ 45130391Skarels 45230391Skarels #define ACC_OFF 0x01 /* acceleration is inactive */ 45330391Skarels 454*32012Smarc int qdputc(); /* used to direct kernel console output * 455*32012Smarc int qdstart(); /* used to direct /dev/console output * 45630391Skarels 457*32012Smarc /* 458*32012Smarc * LK-201 state storage for input console keyboard conversion to ASCII 459*32012Smarc */ 46030391Skarels 461*32012Smarc struct q_keyboard { 46230391Skarels 463*32012Smarc int shift; /* state variables */ 464*32012Smarc int cntrl; 465*32012Smarc int lock; 466*32012Smarc int lastcode; /* last keycode typed */ 467*32012Smarc unsigned kup[8]; /* bits for each keycode*/ 468*32012Smarc unsigned dkeys[8]; /* down/up mode keys */ 469*32012Smarc char last; /* last character */ 47030391Skarels 471*32012Smarc } q_keyboard; 47230391Skarels 47330391Skarels 474*32012Smarc /* 47530391Skarels * 476*32012Smarc * DRIVER FUNCTIONS : 47730391Skarels * 478*32012Smarc */ 47930391Skarels 48030391Skarels /********************************************************************* 48130391Skarels * 48230391Skarels * qdcons_init()... init QDSS as console (before probe routine) 48330391Skarels * 48430391Skarels *********************************************************************/ 48530391Skarels 48630391Skarels qdcons_init() 48730391Skarels { 48830391Skarels register u_int unit; 48930391Skarels 490*32012Smarc struct percpu *pcpu; /* pointer to percpu structure */ 491*32012Smarc register struct qbus *qb; 49230391Skarels int *ptep; /* page table entry pointer */ 49330391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 49430391Skarels u_int mapix; /* index into QMEMmap[] array */ 49530391Skarels 49630391Skarels u_short *qdaddr; /* address of QDSS IO page CSR */ 49730391Skarels u_short *devptr; /* vitual device space */ 498*32012Smarc extern cnputc(); /* standard serial console putc */ 49930391Skarels 50030391Skarels #define QDSSCSR 0x1F00 50130391Skarels 502*32012Smarc /* 503*32012Smarc * if console already configured, dont do again. 504*32012Smarc */ 505*32012Smarc if (v_putc != cnputc) 506*32012Smarc return; 507*32012Smarc 50830391Skarels unit = 0; 50930391Skarels 510*32012Smarc /* 511*32012Smarc * find the cpusw entry that matches this machine. 512*32012Smarc */ 51330391Skarels 514*32012Smarc for (pcpu = percpu; pcpu && pcpu->pc_cputype != cpu; pcpu++) 515*32012Smarc ; 516*32012Smarc if (pcpu == NULL) 517*32012Smarc return; 51830391Skarels 51930391Skarels 520*32012Smarc /* 521*32012Smarc * Map device registers - the last 8K of umem. 522*32012Smarc */ 523*32012Smarc qb = (struct qbus *)pcpu->pc_io->io_details; 524*32012Smarc ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize, 525*32012Smarc UBAIOPAGES * NBPG); 52630391Skarels 527*32012Smarc devptr = (u_short *)((char *)umem[0]+(qb->qb_memsize * NBPG)); 52830391Skarels qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 529*32012Smarc if (badaddr(qdaddr, sizeof(short))) { 530*32012Smarc log(LOG_ERR, "Can't find qdss (badaddr)\n"); /* debug */ 53130391Skarels return(0); 532*32012Smarc } 533*32012Smarc /* 534*32012Smarc * Map q-bus memory used by qdss. (separate map) 535*32012Smarc */ 536*32012Smarc mapix = QMEMSIZE - (CHUNK * (unit + 1)); 537*32012Smarc phys_adr = qb->qb_maddr + mapix; 538*32012Smarc ioaccess(phys_adr, QVmap[0], (CHUNK*NQD)); 53930391Skarels 540*32012Smarc /* 541*32012Smarc * tell QDSS which Q memory address base to decode 542*32012Smarc */ 54330391Skarels 544*32012Smarc /* 545*32012Smarc * shifted right 16 bits - its in 64K units 546*32012Smarc */ 547*32012Smarc *qdaddr = (u_short)((int)mapix >> 16); 54830391Skarels qdflags[unit].config = *(u_short *)qdaddr; 54930391Skarels 550*32012Smarc /* 551*32012Smarc * load qdmap struct with the virtual addresses of the QDSS elements 552*32012Smarc */ 55330391Skarels 554*32012Smarc qdbase[unit] = (caddr_t) qvmem[0]; 55530391Skarels 55630391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 55730391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 55830391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 55930391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 56030391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 56130391Skarels qdmap[unit].red = qdbase[unit] + RED; 56230391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 56330391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 56430391Skarels 56530391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 56630391Skarels 567*32012Smarc /* 568*32012Smarc * init the QDSS 569*32012Smarc */ 57030391Skarels 571*32012Smarc /*** 572*32012Smarc printf("qdbase[0] = %x, qdmap[0].memcsr = %x\n", 573*32012Smarc (char *)qdbase[0], qdmap[0].memcsr); 574*32012Smarc ***/ 575*32012Smarc 57630391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */ 57730391Skarels 57830391Skarels cursor[unit].x = 0; 57930391Skarels cursor[unit].y = 0; 58030391Skarels init_shared(unit); /* init shared memory */ 58130391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 58230391Skarels clear_qd_screen(unit); /* clear the screen */ 58330391Skarels ldfont(unit); /* load the console font */ 58430391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 58530391Skarels setup_input(unit); /* init the DUART */ 58630391Skarels 587*32012Smarc v_putc = qdputc; 588*32012Smarc consops = &cdevsw[QDSSMAJOR]; 58930391Skarels 59030391Skarels return(1); 59130391Skarels 59230391Skarels } /* qdcons_init */ 59330391Skarels 59430391Skarels /********************************************************************* 59530391Skarels * 59630391Skarels * qdprobe()... configure QDSS into Q memory and make it intrpt 59730391Skarels * 59830391Skarels ********************************************************************** 59930391Skarels * 60030391Skarels * calling convention: 60130391Skarels * qdprobe(reg, ctlr); 60230391Skarels * caddr_t reg; 60330391Skarels * int ctlr; 60430391Skarels * 60530391Skarels * where: reg - a character pointer to the QDSS I/O page register 60630391Skarels * ctlr - controller number (?) 60730391Skarels * 60830391Skarels * side effects: QDSS gets mapped into Qbus memory space at the first 60930391Skarels * vacant 64kb boundary counting back from the top of 61030391Skarels * Qbus memory space (qmem+4mb) 61130391Skarels * 61230391Skarels * return: QDSS bus request level and vector address returned in 61330391Skarels * registers by UNIX convention. 61430391Skarels * 61530391Skarels *****************/ 61630391Skarels 61730391Skarels qdprobe(reg) 61830391Skarels caddr_t reg; 61930391Skarels { 620*32012Smarc register int br, cvec; /* value-result */ 62130391Skarels 62230391Skarels register int unit; 62330391Skarels 62430391Skarels struct dga *dga; /* pointer to gate array structure */ 62530391Skarels struct cpusw *cpup; /* pointer to the cpusw structure */ 62630391Skarels 62730391Skarels int *ptep; /* page table entry pointer */ 62830391Skarels int vector; 62930391Skarels 63030391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 63130391Skarels u_int mapix; 63230391Skarels 633*32012Smarc #ifdef lint 634*32012Smarc br = 0; cvec = br; br = cvec; 635*32012Smarc #endif 63630391Skarels 637*32012Smarc /* 638*32012Smarc * calculate board unit number from I/O page register address 639*32012Smarc */ 640*32012Smarc 64130391Skarels unit = (int) (((int)reg >> 1) & 0x0007); 64230391Skarels 643*32012Smarc /* 64430391Skarels * QDSS regs must be mapped to Qbus memory space at a 64kb physical boundary. 64530391Skarels * The Qbus memory space is mapped into the system memory space at config 64630391Skarels * time. After config runs, "qmem[0]" (ubavar.h) holds the system virtual adrs 64730391Skarels * of the start of Qbus memory. The Qbus memory page table is found via 64830391Skarels * an array of pte ptrs called "QMEMmap[]" (ubavar.h) which is also loaded at 64930391Skarels * config time. These are the variables used below to find a vacant 64kb 65030391Skarels * boundary in Qbus memory, and load it's corresponding physical adrs into 651*32012Smarc * the QDSS's I/O page CSR. 652*32012Smarc */ 65330391Skarels 65430391Skarels /* if this QDSS is NOT the console, then do init here.. */ 65530391Skarels 656*32012Smarc /****** NOT FOR NOW - DO LATER (FARKLE) ***/ 657*32012Smarc #ifdef notdef 65830391Skarels if (v_consputc != qdputc || unit != 0) { 65930391Skarels 660*32012Smarc /* 661*32012Smarc * read QDSS config info 662*32012Smarc */ 66330391Skarels qdflags[unit].config = *(u_short *)reg; 66430391Skarels 665*32012Smarc /* 666*32012Smarc * find an empty 64kb adrs boundary 667*32012Smarc */ 66830391Skarels qdbase[unit] = (caddr_t) (qmem[0] + QMEMSIZE - CHUNK); 66930391Skarels 670*32012Smarc /* 671*32012Smarc * find the cpusw entry that matches this machine. 672*32012Smarc */ 67330391Skarels cpup = &cpusw[cpu]; 67430391Skarels while ( !(BADADDR(qdbase[unit], sizeof(short))) ) 67530391Skarels qdbase[unit] -= CHUNK; 67630391Skarels 677*32012Smarc /* 678*32012Smarc * tell QDSS which Q memory address base to decode 679*32012Smarc */ 68030391Skarels mapix = (int) (VTOP(qdbase[unit]) - VTOP(qmem[0])); 68130391Skarels ptep = (int *) QMEMmap[0] + mapix; 68230391Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 68330391Skarels *(u_short *)reg = (u_short) ((int)phys_adr >> 16); 68430391Skarels 685*32012Smarc /* 686*32012Smarc * load QDSS adrs map with system addresses of device regs 687*32012Smarc */ 68830391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 68930391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 69030391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 69130391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 69230391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 69330391Skarels qdmap[unit].red = qdbase[unit] + RED; 69430391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 69530391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 69630391Skarels 69730391Skarels /* device init */ 69830391Skarels 69930391Skarels cursor[unit].x = 0; 70030391Skarels cursor[unit].y = 0; 70130391Skarels init_shared(unit); /* init shared memory */ 70230391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 70330391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 70430391Skarels setup_input(unit); /* init the DUART */ 70530391Skarels clear_qd_screen(unit); 70630391Skarels ldfont(unit); /* load the console font */ 70730391Skarels 70830391Skarels /* once only: turn on sync */ 70930391Skarels 71030391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; 71130391Skarels } 712*32012Smarc #endif notdef 71330391Skarels 714*32012Smarc /* 715*32012Smarc * the QDSS interrupts at HEX vectors xx0 (DMA) xx4 (ADDER) and xx8 (DUART). 716*32012Smarc * Therefore, we take three vectors from the vector pool, and then continue 717*32012Smarc * to take them until we get a xx0 HEX vector. The pool provides vectors 718*32012Smarc * in contiguous decending order. 719*32012Smarc */ 72030391Skarels 72130391Skarels vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ 72230391Skarels 72330391Skarels while (vector & 0x0F) { /* if lo nibble != 0.. */ 72430391Skarels vector = (uba_hd[0].uh_lastiv -= 4); /* ..take another vector */ 72530391Skarels } 72630391Skarels 727*32012Smarc /* 728*32012Smarc * setup DGA to do a DMA interrupt (transfer count = 0) 729*32012Smarc */ 73030391Skarels 73130391Skarels dga = (struct dga *) qdmap[unit].dga; 73230391Skarels 73330391Skarels dga->csr = (short) HALT; /* disable everything */ 73430391Skarels dga->ivr = (short) vector; /* load intrpt base vector */ 73530391Skarels dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ 73630391Skarels dga->bytcnt_hi = (short) 0; 73730391Skarels 73830391Skarels /* turn on DMA interrupts */ 73930391Skarels 74030391Skarels dga->csr &= ~SET_DONE_FIFO; 74130391Skarels dga->csr |= DMA_IE | DL_ENB; 74230391Skarels 74330391Skarels DELAY(20000); /* wait for the intrpt */ 74430391Skarels 74530391Skarels dga->csr = HALT; /* stop the wheels */ 74630391Skarels 74730391Skarels if (cvec != vector) /* if vector != base vector.. */ 74830391Skarels return(0); /* ..return = 'no device' */ 74930391Skarels 75030391Skarels return(sizeof(short)); /* return size of QDSS I/O page reg */ 75130391Skarels 75230391Skarels } /* qdprobe */ 75330391Skarels 75430391Skarels /***************************************************************** 75530391Skarels * 75630391Skarels * qdattach()... do the one-time initialization 75730391Skarels * 75830391Skarels ****************************************************************** 75930391Skarels * 76030391Skarels * calling convention: 76130391Skarels * qdattach(ui); 76230391Skarels * struct uba_device *ui; 76330391Skarels * 76430391Skarels * where: ui - pointer to the QDSS's uba_device structure 76530391Skarels * 76630391Skarels * side effects: none 76730391Skarels * return: none 76830391Skarels * 76930391Skarels *************************/ 77030391Skarels 77130391Skarels qdattach(ui) 77230391Skarels struct uba_device *ui; 77330391Skarels { 77430391Skarels register u_int unit; /* QDSS module # for this call */ 77530391Skarels 77630391Skarels unit = ui->ui_unit; /* get QDSS number */ 77730391Skarels 778*32012Smarc /* 779*32012Smarc * init "qdflags[]" for this QDSS 780*32012Smarc */ 78130391Skarels 78230391Skarels qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ 78330391Skarels qdflags[unit].mapped = 0; 78430391Skarels qdflags[unit].kernel_loop = 0; 78530391Skarels qdflags[unit].user_dma = 0; 78630391Skarels qdflags[unit].curs_acc = ACC_OFF; 78730391Skarels qdflags[unit].curs_thr = 128; 78830391Skarels qdflags[unit].tab_res = 2; /* default tablet resolution factor */ 78930391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 79030391Skarels qdflags[unit].adder_ie = 0; 79130391Skarels 792*32012Smarc /* 79330391Skarels * init structures used in kbd/mouse interrupt service. This code must 79430391Skarels * come after the "init_shared()" routine has run since that routine inits 795*32012Smarc * the eq_header[unit] structure used here. 796*32012Smarc */ 79730391Skarels 798*32012Smarc /* 799*32012Smarc * init the "latest mouse report" structure 800*32012Smarc */ 80130391Skarels 80230391Skarels last_rep[unit].state = 0; 80330391Skarels last_rep[unit].dx = 0; 80430391Skarels last_rep[unit].dy = 0; 80530391Skarels last_rep[unit].bytcnt = 0; 80630391Skarels 80730391Skarels /*------------------------------------------------ 80830391Skarels * init the event queue (except mouse position) */ 80930391Skarels 81030391Skarels eq_header[unit]->header.events = (struct _vs_event *) 81130391Skarels ((int)eq_header[unit] 81230391Skarels + sizeof(struct qdinput)); 81330391Skarels 81430391Skarels eq_header[unit]->header.size = MAXEVENTS; 81530391Skarels eq_header[unit]->header.head = 0; 81630391Skarels eq_header[unit]->header.tail = 0; 81730391Skarels 818*32012Smarc /* 819*32012Smarc * init single process access lock switch 820*32012Smarc */ 82130391Skarels 82230391Skarels one_only[unit] = 0; 82330391Skarels 82430391Skarels } /* qdattach */ 82530391Skarels 82630391Skarels /*************************************************************** 82730391Skarels * 82830391Skarels * qdopen()... open a minor device 82930391Skarels * 83030391Skarels **************************************************************** 83130391Skarels * 83230391Skarels * calling convention: qdopen(dev, flag); 83330391Skarels * dev_t dev; 83430391Skarels * int flag; 83530391Skarels * 83630391Skarels * side effects: none 83730391Skarels * 83830391Skarels *********************/ 83930391Skarels 84030391Skarels qdopen(dev, flag) 84130391Skarels dev_t dev; 84230391Skarels int flag; 84330391Skarels { 84430391Skarels register struct uba_device *ui; /* ptr to uba structures */ 84530391Skarels register struct dga *dga; /* ptr to gate array struct */ 84630391Skarels register struct tty *tp; 847*32012Smarc int qdstart(); 84830391Skarels 84930391Skarels struct adder *adder; 85030391Skarels struct duart *duart; 85130391Skarels 85230391Skarels u_int unit; 85330391Skarels u_int minor_dev; 85430391Skarels int s; 85530391Skarels 85630391Skarels minor_dev = minor(dev); /* get QDSS minor device number */ 85730391Skarels unit = minor_dev >> 2; 85830391Skarels 859*32012Smarc /* check for illegal conditions */ 86030391Skarels 86130391Skarels ui = qdinfo[unit]; /* get ptr to QDSS device struct */ 86230391Skarels 86330391Skarels if (ui == 0 || ui->ui_alive == 0) 86430391Skarels return(ENXIO); /* no such device or address */ 86530391Skarels 866*32012Smarc /* init stuff */ 86730391Skarels 86830391Skarels adder = (struct adder *) qdmap[unit].adder; 86930391Skarels duart = (struct duart *) qdmap[unit].duart; 87030391Skarels dga = (struct dga *) qdmap[unit].dga; 87130391Skarels 872*32012Smarc /* if this is the graphic device... */ 87330391Skarels 87430391Skarels if ((minor_dev & 0x03) == 2) { 87530391Skarels 87630391Skarels if (one_only[unit] != 0) 87730391Skarels return(EBUSY); 87830391Skarels else 87930391Skarels one_only[unit] = 1; 88030391Skarels 88130391Skarels qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ 88230391Skarels 88330391Skarels /* enble kbd & mouse intrpts in DUART mask reg */ 88430391Skarels 88530391Skarels qdflags[unit].duart_imask |= 0x22; 88630391Skarels duart->imask = qdflags[unit].duart_imask; 88730391Skarels 888*32012Smarc /* 889*32012Smarc * if the open call is to the console or the alternate console... 890*32012Smarc */ 891*32012Smarc } else { 89230391Skarels 89330391Skarels qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ 89430391Skarels dga->csr |= CURS_ENB; 89530391Skarels 89630391Skarels qdflags[unit].duart_imask |= 0x02; 89730391Skarels duart->imask = qdflags[unit].duart_imask; 89830391Skarels 89930391Skarels /*------------------------------- 90030391Skarels * some setup for tty handling */ 90130391Skarels 90230391Skarels tp = &qd_tty[minor_dev]; 90330391Skarels 90430391Skarels tp->t_addr = ui->ui_addr; 90530391Skarels tp->t_oproc = qdstart; 90630391Skarels 90730391Skarels if ((tp->t_state & TS_ISOPEN) == 0) { 90830391Skarels 90930391Skarels ttychars(tp); 91030391Skarels tp->t_state = TS_ISOPEN | TS_CARR_ON; 91130391Skarels tp->t_ispeed = B9600; 91230391Skarels tp->t_ospeed = B9600; 91330391Skarels 914*32012Smarc if( (minor_dev & 0x03) == 0 ) { 91530391Skarels tp->t_flags = XTABS|EVENP|ECHO|CRMOD; 916*32012Smarc } 917*32012Smarc else { 91830391Skarels tp->t_flags = RAW; 919*32012Smarc } 92030391Skarels } 92130391Skarels 92230391Skarels /*---------------------------------------- 92330391Skarels * enable intrpts, open line discipline */ 92430391Skarels 92530391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 92630391Skarels return ((*linesw[tp->t_line].l_open)(dev, tp)); 92730391Skarels } 92830391Skarels 92930391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 93030391Skarels return(0); 93130391Skarels 93230391Skarels } /* qdopen */ 93330391Skarels 93430391Skarels /*************************************************************** 93530391Skarels * 93630391Skarels * qdclose()... clean up on the way out 93730391Skarels * 93830391Skarels **************************************************************** 93930391Skarels * 94030391Skarels * calling convention: qdclose(); 94130391Skarels * 94230391Skarels * side effects: none 94330391Skarels * 94430391Skarels * return: none 94530391Skarels * 94630391Skarels *********************/ 94730391Skarels 94830391Skarels qdclose(dev, flag) 94930391Skarels dev_t dev; 95030391Skarels int flag; 95130391Skarels { 95230391Skarels register struct tty *tp; 95330391Skarels register struct qdmap *qd; 95430391Skarels register int *ptep; 95530391Skarels int i; /* SIGNED index */ 95630391Skarels 95730391Skarels struct dga *dga; /* gate array register map pointer */ 95830391Skarels struct duart *duart; 95930391Skarels struct adder *adder; 96030391Skarels 96130391Skarels u_int unit; 96230391Skarels u_int minor_dev; 96330391Skarels u_int mapix; 96430391Skarels 96530391Skarels minor_dev = minor(dev); /* get minor device number */ 96630391Skarels unit = minor_dev >> 2; /* get QDSS number */ 96730391Skarels qd = &qdmap[unit]; 96830391Skarels 969*32012Smarc /* 970*32012Smarc * if this is the graphic device... 971*32012Smarc */ 97230391Skarels 97330391Skarels if ((minor_dev & 0x03) == 2) { 97430391Skarels 97530391Skarels /*----------------- 97630391Skarels * unlock driver */ 97730391Skarels 97830391Skarels if (one_only[unit] != 1) 97930391Skarels return(EBUSY); 98030391Skarels else 98130391Skarels one_only[unit] = 0; 98230391Skarels 98330391Skarels /*---------------------------- 98430391Skarels * re-protect device memory */ 98530391Skarels 98630391Skarels if (qdflags[unit].mapped & MAPDEV) { 98730391Skarels 98830391Skarels /*---------------- 98930391Skarels * TEMPLATE RAM */ 99030391Skarels 991*32012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 992*32012Smarc ptep = (int *)(QVmap[0] + mapix); 99330391Skarels 99430391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 99530391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 99630391Skarels 99730391Skarels /*--------- 99830391Skarels * ADDER */ 99930391Skarels 1000*32012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 1001*32012Smarc ptep = (int *)(QVmap[0] + mapix); 100230391Skarels 100330391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 100430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 100530391Skarels 100630391Skarels /*-------------- 100730391Skarels * COLOR MAPS */ 100830391Skarels 1009*32012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 1010*32012Smarc ptep = (int *)(QVmap[0] + mapix); 101130391Skarels 101230391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 101330391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 101430391Skarels } 101530391Skarels 101630391Skarels /*---------------------------------------------------- 101730391Skarels * re-protect DMA buffer and free the map registers */ 101830391Skarels 101930391Skarels if (qdflags[unit].mapped & MAPDMA) { 102030391Skarels 102130391Skarels dga = (struct dga *) qdmap[unit].dga; 102230391Skarels adder = (struct adder *) qdmap[unit].adder; 102330391Skarels 102430391Skarels dga->csr &= ~DMA_IE; 102530391Skarels dga->csr &= ~0x0600; /* kill DMA */ 102630391Skarels adder->command = CANCEL; 102730391Skarels 102830391Skarels /* if DMA was running, flush spurious intrpt */ 102930391Skarels 103030391Skarels if (dga->bytcnt_lo != 0) { 103130391Skarels dga->bytcnt_lo = 0; 103230391Skarels dga->bytcnt_hi = 0; 103330391Skarels DMA_SETIGNORE(DMAheader[unit]); 103430391Skarels dga->csr |= DMA_IE; 103530391Skarels dga->csr &= ~DMA_IE; 103630391Skarels } 103730391Skarels 103830391Skarels ptep = (int *) 103930391Skarels ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); 104030391Skarels 104130391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 104230391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 104330391Skarels 104430391Skarels ubarelse(0, &Qbus_unmap[unit]); 104530391Skarels } 104630391Skarels 104730391Skarels /*--------------------------------------- 104830391Skarels * re-protect 1K (2 pages) event queue */ 104930391Skarels 105030391Skarels if (qdflags[unit].mapped & MAPEQ) { 105130391Skarels 105230391Skarels ptep = (int *) 105330391Skarels ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); 105430391Skarels 105530391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 105630391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 105730391Skarels } 105830391Skarels 105930391Skarels /*------------------------------------------------------------ 106030391Skarels * re-protect scroll param area and disable scroll intrpts */ 106130391Skarels 106230391Skarels if (qdflags[unit].mapped & MAPSCR) { 106330391Skarels 106430391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 106530391Skarels + (mfpr(SBR) | 0x80000000)); 106630391Skarels 106730391Skarels /* re-protect 512 scroll param area */ 106830391Skarels 106930391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 107030391Skarels 107130391Skarels adder = (struct adder *) qdmap[unit].adder; 107230391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 107330391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 107430391Skarels } 107530391Skarels 107630391Skarels /*----------------------------------------------------------- 107730391Skarels * re-protect color map write buffer area and kill intrpts */ 107830391Skarels 107930391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 108030391Skarels 108130391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 108230391Skarels + (mfpr(SBR) | 0x80000000)); 108330391Skarels 108430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 108530391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 108630391Skarels 108730391Skarels color_buf[unit]->status = 0; 108830391Skarels 108930391Skarels adder = (struct adder *) qdmap[unit].adder; 109030391Skarels qdflags[unit].adder_ie &= ~VSYNC; 109130391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 109230391Skarels } 109330391Skarels 109430391Skarels /*----------------------------------- 109530391Skarels * flag that everthing is unmapped */ 109630391Skarels 109730391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 109830391Skarels qdflags[unit].mapped = 0; /* flag everything now unmapped */ 109930391Skarels qdflags[unit].inuse &= ~GRAPHIC_DEV; 110030391Skarels qdflags[unit].curs_acc = ACC_OFF; 110130391Skarels qdflags[unit].curs_thr = 128; 110230391Skarels 110330391Skarels /*--------------------- 110430391Skarels * restore the console */ 110530391Skarels 110630391Skarels dga = (struct dga *) qdmap[unit].dga; 110730391Skarels adder = (struct adder *) qdmap[unit].adder; 110830391Skarels 110930391Skarels dga->csr &= ~DMA_IE; 111030391Skarels dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ 111130391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 111230391Skarels adder->command = CANCEL; 111330391Skarels 111430391Skarels /* if DMA was running, flush spurious intrpt */ 111530391Skarels 111630391Skarels if (dga->bytcnt_lo != 0) { 111730391Skarels dga->bytcnt_lo = 0; 111830391Skarels dga->bytcnt_hi = 0; 111930391Skarels DMA_SETIGNORE(DMAheader[unit]); 112030391Skarels dga->csr |= DMA_IE; 112130391Skarels dga->csr &= ~DMA_IE; 112230391Skarels } 112330391Skarels 112430391Skarels init_shared(unit); /* init shared memory */ 112530391Skarels setup_dragon(unit); /* init ADDER/VIPER */ 112630391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 112730391Skarels setup_input(unit); /* init the DUART */ 112830391Skarels ldfont(unit); 112930391Skarels cursor[unit].x = 0; 113030391Skarels cursor[unit].y = 0; 113130391Skarels 113230391Skarels /* shut off the mouse rcv intrpt and turn on kbd intrpts */ 113330391Skarels 113430391Skarels duart = (struct duart *) qdmap[unit].duart; 113530391Skarels qdflags[unit].duart_imask &= ~(0x20); 113630391Skarels qdflags[unit].duart_imask |= 0x02; 113730391Skarels duart->imask = qdflags[unit].duart_imask; 113830391Skarels 113930391Skarels /*----------------------------------------- 114030391Skarels * shut off interrupts if all is closed */ 114130391Skarels 114230391Skarels if (!(qdflags[unit].inuse & (CONS_DEV | ALTCONS_DEV))) { 114330391Skarels 114430391Skarels dga = (struct dga *) qdmap[unit].dga; 114530391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 114630391Skarels } 114730391Skarels } 114830391Skarels else { 1149*32012Smarc /* if this is the console or the alternate console */ 115030391Skarels 115130391Skarels tp = &qd_tty[minor_dev]; 115230391Skarels 115330391Skarels (*linesw[tp->t_line].l_close)(tp); 115430391Skarels ttyclose(tp); 115530391Skarels 115630391Skarels tp->t_state = 0; 115730391Skarels 115830391Skarels qdflags[unit].inuse &= ~CONS_DEV; 115930391Skarels 116030391Skarels /*------------------------------------------------- 116130391Skarels * if graphics device is closed, kill interrupts */ 116230391Skarels 116330391Skarels if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { 116430391Skarels dga = (struct dga *) qdmap[unit].dga; 116530391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 116630391Skarels } 116730391Skarels } 116830391Skarels 116930391Skarels return(0); 117030391Skarels 117130391Skarels } /* qdclose */ 117230391Skarels 117330391Skarels /*************************************************************** 117430391Skarels * 117530391Skarels * qdioctl()... provide QDSS control services 117630391Skarels * 117730391Skarels **************************************************************** 117830391Skarels * 117930391Skarels * calling convention: qdioctl(dev, cmd, datap, flags); 118030391Skarels * 118130391Skarels * where: dev - the major/minor device number 118230391Skarels * cmd - the user-passed command argument 118330391Skarels * datap - ptr to user input buff (128 bytes max) 118430391Skarels * flags - "f_flags" from "struct file" in file.h 118530391Skarels * 118630391Skarels * 118730391Skarels * - here is the format for the input "cmd" argument 118830391Skarels * 118930391Skarels * 31 29 28 23 22 16 15 8 7 0 119030391Skarels * +----------------------------------------------------------------+ 119130391Skarels * |I/O type| | buff length | device ID char | user command | 119230391Skarels * +----------------------------------------------------------------+ 119330391Skarels * 119430391Skarels * Return data is in the data buffer pointed to by "datap" input spec 119530391Skarels * 119630391Skarels *********************/ 119730391Skarels 119830391Skarels qdioctl(dev, cmd, datap, flags) 119930391Skarels dev_t dev; 120030391Skarels int cmd; 120130391Skarels caddr_t datap; 120230391Skarels int flags; 120330391Skarels { 120430391Skarels register int *ptep; /* page table entry pointer */ 1205*32012Smarc register int mapix; /* QVmap[] page table index */ 120630391Skarels register struct _vs_event *event; 120730391Skarels register struct tty *tp; 120830391Skarels 120930391Skarels struct qdmap *qd; /* pointer to device map struct */ 121030391Skarels struct dga *dga; /* Gate Array reg structure pntr */ 121130391Skarels struct duart *duart; /* DUART reg structure pointer */ 121230391Skarels struct adder *adder; /* ADDER reg structure pointer */ 121330391Skarels 121430391Skarels struct prgkbd *cmdbuf; 121530391Skarels struct prg_cursor *curs; 121630391Skarels struct _vs_cursor *pos; 121730391Skarels 121830391Skarels u_int unit = minor(dev) >> 2; /* number of caller's QDSS */ 121930391Skarels u_int minor_dev = minor(dev); 122030391Skarels struct uba_device *ui = qdinfo[unit]; 122130391Skarels struct qd_softc *sc = &qd_softc[ui->ui_unit]; 1222*32012Smarc /* struct devget *devget; */ 122330391Skarels 122430391Skarels int error; 122530391Skarels int s; 122630391Skarels 122730391Skarels int i; /* SIGNED index */ 122830391Skarels int sbr; /* SBR variable (you silly boy) */ 122930391Skarels u_int ix; 123030391Skarels 123130391Skarels short status; 123230391Skarels short *shortp; /* generic pointer to a short */ 123330391Skarels char *chrp; /* generic character pointer */ 123430391Skarels 123530391Skarels short *temp; /* a pointer to template RAM */ 123630391Skarels 1237*32012Smarc /* service graphic device ioctl commands */ 123830391Skarels switch (cmd) { 123930391Skarels 124030391Skarels /*------------------------------------------------- 124130391Skarels * extract the oldest event from the event queue */ 124230391Skarels 124330391Skarels case QD_GETEVENT: 124430391Skarels 124530391Skarels if (ISEMPTY(eq_header[unit])) { 124630391Skarels event = (struct _vs_event *) datap; 124730391Skarels event->vse_device = VSE_NULL; 124830391Skarels break; 124930391Skarels } 125030391Skarels 125130391Skarels event = (struct _vs_event *) GETBEGIN(eq_header[unit]); 1252*32012Smarc s = spltty(); 125330391Skarels GETEND(eq_header[unit]); 125430391Skarels splx(s); 125530391Skarels bcopy(event, datap, sizeof(struct _vs_event)); 125630391Skarels break; 125730391Skarels 125830391Skarels /*------------------------------------------------------- 125930391Skarels * init the dragon stuff, DUART, and driver variables */ 126030391Skarels 126130391Skarels case QD_RESET: 126230391Skarels 126330391Skarels init_shared(unit); /* init shared memory */ 126430391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 126530391Skarels clear_qd_screen(unit); 126630391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 126730391Skarels ldfont(unit); /* load the console font */ 126830391Skarels setup_input(unit); /* init the DUART */ 126930391Skarels break; 127030391Skarels 127130391Skarels /*---------------------------------------- 127230391Skarels * init the DUART and driver variables */ 127330391Skarels 127430391Skarels case QD_SET: 127530391Skarels 127630391Skarels init_shared(unit); 127730391Skarels setup_input(unit); 127830391Skarels break; 127930391Skarels 128030391Skarels /*--------------------------------------------------------------- 128130391Skarels * clear the QDSS screen. (NOTE that this reinits the dragon) */ 128230391Skarels 128330391Skarels case QD_CLRSCRN: 128430391Skarels 128530391Skarels setup_dragon(unit); 128630391Skarels clear_qd_screen(unit); 128730391Skarels break; 128830391Skarels 128930391Skarels /*------------------------------------ 129030391Skarels * load a cursor into template RAM */ 129130391Skarels 129230391Skarels case QD_WTCURSOR: 129330391Skarels 129430391Skarels ldcursor(unit, datap); 129530391Skarels break; 129630391Skarels 129730391Skarels case QD_RDCURSOR: 129830391Skarels 129930391Skarels temp = (short *) qdmap[unit].template; 130030391Skarels 130130391Skarels /* cursor is 32 WORDS from the end of the 8k WORD... 130230391Skarels * ...template space */ 130330391Skarels 130430391Skarels temp += (8 * 1024) - 32; 130530391Skarels 130630391Skarels for (i = 0; i < 32; ++i, datap += sizeof(short)) 130730391Skarels *(short *)datap = *temp++; 130830391Skarels break; 130930391Skarels 131030391Skarels /*------------------------------ 131130391Skarels * position the mouse cursor */ 131230391Skarels 131330391Skarels case QD_POSCURSOR: 131430391Skarels 131530391Skarels dga = (struct dga *) qdmap[unit].dga; 131630391Skarels pos = (struct _vs_cursor *) datap; 1317*32012Smarc s = spltty(); 131830391Skarels dga->x_cursor = TRANX(pos->x); 131930391Skarels dga->y_cursor = TRANY(pos->y); 132030391Skarels eq_header[unit]->curs_pos.x = pos->x; 132130391Skarels eq_header[unit]->curs_pos.y = pos->y; 132230391Skarels splx(s); 132330391Skarels break; 132430391Skarels 132530391Skarels /*-------------------------------------- 132630391Skarels * set the cursor acceleration factor */ 132730391Skarels 132830391Skarels case QD_PRGCURSOR: 132930391Skarels 133030391Skarels curs = (struct prg_cursor *) datap; 1331*32012Smarc s = spltty(); 133230391Skarels qdflags[unit].curs_acc = curs->acc_factor; 133330391Skarels qdflags[unit].curs_thr = curs->threshold; 133430391Skarels splx(s); 133530391Skarels break; 133630391Skarels 133730391Skarels /*--------------------------------------- 133830391Skarels * enable 'user write' to device pages */ 133930391Skarels 134030391Skarels case QD_MAPDEVICE: 134130391Skarels 134230391Skarels /*-------------- 134330391Skarels * init stuff */ 134430391Skarels 134530391Skarels qdflags[unit].mapped |= MAPDEV; 134630391Skarels qd = (struct qdmap *) &qdmap[unit]; 134730391Skarels 134830391Skarels /*------------------------------------- 134930391Skarels * enable user write to template RAM */ 135030391Skarels 1351*32012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 1352*32012Smarc ptep = (int *)(QVmap[0] + mapix); 135330391Skarels 135430391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 135530391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 135630391Skarels 135730391Skarels /*---------------------------------- 135830391Skarels * enable user write to registers */ 135930391Skarels 1360*32012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 1361*32012Smarc ptep = (int *)(QVmap[0] + mapix); 136230391Skarels 136330391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 136430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 136530391Skarels 136630391Skarels /*----------------------------------- 136730391Skarels * enable user write to color maps */ 136830391Skarels 1369*32012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 1370*32012Smarc ptep = (int *)(QVmap[0] + mapix); 137130391Skarels 137230391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 137330391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 137430391Skarels 137530391Skarels /*------------------------------ 137630391Skarels * enable user write to DUART */ 137730391Skarels 1378*32012Smarc mapix = VTOP((int)qd->duart) - VTOP(qvmem[0]); 1379*32012Smarc ptep = (int *)(QVmap[0] + mapix); 138030391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ 138130391Skarels 138230391Skarels mtpr(TBIA, 0); /* smash CPU's translation buffer */ 138330391Skarels 138430391Skarels /*------------------------------------------ 138530391Skarels * stuff qdmap structure in return buffer */ 138630391Skarels 138730391Skarels bcopy(qd, datap, sizeof(struct qdmap)); 138830391Skarels break; 138930391Skarels 139030391Skarels /*------------------------------------- 139130391Skarels * do setup for DMA by user process */ 139230391Skarels 139330391Skarels case QD_MAPIOBUF: 139430391Skarels 139530391Skarels /*------------------------------------------------ 139630391Skarels * set 'user write enable' bits for DMA buffer */ 139730391Skarels 139830391Skarels qdflags[unit].mapped |= MAPDMA; 139930391Skarels 140030391Skarels ptep = (int *) ((VTOP(DMAheader[unit]) * 4) 140130391Skarels + (mfpr(SBR) | 0x80000000)); 140230391Skarels 140330391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 140430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 140530391Skarels 140630391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 140730391Skarels 140830391Skarels /*------------------------------------- 140930391Skarels * set up QBUS map registers for DMA */ 141030391Skarels 141130391Skarels DMAheader[unit]->QBAreg = 141230391Skarels uballoc(0, DMAheader[unit], DMAbuf_size, 0); 141330391Skarels 141430391Skarels if (DMAheader[unit]->QBAreg == 0) 141530391Skarels mprintf("\nqd%d: qdioctl: QBA setup error", unit); 141630391Skarels 141730391Skarels Qbus_unmap[unit] = DMAheader[unit]->QBAreg; 141830391Skarels DMAheader[unit]->QBAreg &= 0x3FFFF; 141930391Skarels 142030391Skarels /*---------------------- 142130391Skarels * return I/O buf adr */ 142230391Skarels 142330391Skarels *(int *)datap = (int) DMAheader[unit]; 142430391Skarels break; 142530391Skarels 142630391Skarels /*---------------------------------------------------------------- 142730391Skarels * map the shared scroll param area and enable scroll interpts */ 142830391Skarels 142930391Skarels case QD_MAPSCROLL: 143030391Skarels 143130391Skarels qdflags[unit].mapped |= MAPSCR; 143230391Skarels 143330391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 143430391Skarels + (mfpr(SBR) | 0x80000000)); 143530391Skarels 143630391Skarels /* allow user write to scroll area */ 143730391Skarels 143830391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 143930391Skarels 144030391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 144130391Skarels 144230391Skarels scroll[unit]->status = 0; 144330391Skarels 144430391Skarels adder = (struct adder *) qdmap[unit].adder; 144530391Skarels 144630391Skarels qdflags[unit].adder_ie |= FRAME_SYNC; 144730391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 144830391Skarels 144930391Skarels /* return scroll area address */ 145030391Skarels 145130391Skarels *(int *)datap = (int) scroll[unit]; 145230391Skarels break; 145330391Skarels 145430391Skarels /*------------------------------------------------------------- 145530391Skarels * unmap shared scroll param area and disable scroll intrpts */ 145630391Skarels 145730391Skarels case QD_UNMAPSCROLL: 145830391Skarels 145930391Skarels if (qdflags[unit].mapped & MAPSCR) { 146030391Skarels 146130391Skarels qdflags[unit].mapped &= ~MAPSCR; 146230391Skarels 146330391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 146430391Skarels + (mfpr(SBR) | 0x80000000)); 146530391Skarels 146630391Skarels /* re-protect 512 scroll param area */ 146730391Skarels 146830391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 146930391Skarels 147030391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 147130391Skarels 147230391Skarels adder = (struct adder *) qdmap[unit].adder; 147330391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 147430391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 147530391Skarels } 147630391Skarels break; 147730391Skarels 147830391Skarels /*----------------------------------------------------------- 147930391Skarels * map shared color map write buf and turn on vsync intrpt */ 148030391Skarels 148130391Skarels case QD_MAPCOLOR: 148230391Skarels 148330391Skarels qdflags[unit].mapped |= MAPCOLOR; 148430391Skarels 148530391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 148630391Skarels + (mfpr(SBR) | 0x80000000)); 148730391Skarels 148830391Skarels /* allow user write to color map write buffer */ 148930391Skarels 149030391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 149130391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 149230391Skarels 149330391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 149430391Skarels 149530391Skarels adder = (struct adder *) qdmap[unit].adder; 149630391Skarels 149730391Skarels qdflags[unit].adder_ie |= VSYNC; 149830391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 149930391Skarels 150030391Skarels /* return scroll area address */ 150130391Skarels 150230391Skarels *(int *)datap = (int) color_buf[unit]; 150330391Skarels break; 150430391Skarels 150530391Skarels /*-------------------------------------------------------------- 150630391Skarels * unmap shared color map write buffer and kill VSYNC intrpts */ 150730391Skarels 150830391Skarels case QD_UNMAPCOLOR: 150930391Skarels 151030391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 151130391Skarels 151230391Skarels qdflags[unit].mapped &= ~MAPCOLOR; 151330391Skarels 151430391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 151530391Skarels + (mfpr(SBR) | 0x80000000)); 151630391Skarels 151730391Skarels /* re-protect color map write buffer */ 151830391Skarels 151930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 152030391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 152130391Skarels 152230391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 152330391Skarels 152430391Skarels adder = (struct adder *) qdmap[unit].adder; 152530391Skarels 152630391Skarels qdflags[unit].adder_ie &= ~VSYNC; 152730391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 152830391Skarels } 152930391Skarels break; 153030391Skarels 153130391Skarels /*--------------------------------------------- 153230391Skarels * give user write access to the event queue */ 153330391Skarels 153430391Skarels case QD_MAPEVENT: 153530391Skarels 153630391Skarels qdflags[unit].mapped |= MAPEQ; 153730391Skarels 153830391Skarels ptep = (int *) ((VTOP(eq_header[unit]) * 4) 153930391Skarels + (mfpr(SBR) | 0x80000000)); 154030391Skarels 154130391Skarels /* allow user write to 1K event queue */ 154230391Skarels 154330391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 154430391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 154530391Skarels 154630391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 154730391Skarels 154830391Skarels /* return event queue address */ 154930391Skarels 155030391Skarels *(int *)datap = (int) eq_header[unit]; 155130391Skarels break; 155230391Skarels 155330391Skarels /*----------------------------------------------- 155430391Skarels * pass caller's programming commands to LK201 */ 155530391Skarels 155630391Skarels case QD_PRGKBD: 155730391Skarels 155830391Skarels duart = (struct duart *) qdmap[unit].duart; 155930391Skarels cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ 156030391Skarels 156130391Skarels /*---------------- 156230391Skarels * send command */ 156330391Skarels 156430391Skarels for (i = 1000; i > 0; --i) { 156530391Skarels if ((status = duart->statusA) & XMT_RDY) { 156630391Skarels duart->dataA = cmdbuf->cmd; 156730391Skarels break; 156830391Skarels } 156930391Skarels } 157030391Skarels 157130391Skarels if (i == 0) { 157230391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [1]", unit); 157330391Skarels break; 157430391Skarels } 157530391Skarels 157630391Skarels /*---------------- 157730391Skarels * send param1? */ 157830391Skarels 157930391Skarels if (cmdbuf->cmd & LAST_PARAM) 158030391Skarels break; 158130391Skarels 158230391Skarels for (i = 1000; i > 0; --i) { 158330391Skarels if ((status = duart->statusA) & XMT_RDY) { 158430391Skarels duart->dataA = cmdbuf->param1; 158530391Skarels break; 158630391Skarels } 158730391Skarels } 158830391Skarels 158930391Skarels if (i == 0) { 159030391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [2]", unit); 159130391Skarels break; 159230391Skarels } 159330391Skarels 159430391Skarels /*---------------- 159530391Skarels * send param2? */ 159630391Skarels 159730391Skarels if (cmdbuf->param1 & LAST_PARAM) 159830391Skarels break; 159930391Skarels 160030391Skarels for (i = 1000; i > 0; --i) { 160130391Skarels if ((status = duart->statusA) & XMT_RDY) { 160230391Skarels duart->dataA = cmdbuf->param2; 160330391Skarels break; 160430391Skarels } 160530391Skarels } 160630391Skarels 160730391Skarels if (i == 0) { 160830391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [3]", unit); 160930391Skarels break; 161030391Skarels } 161130391Skarels 161230391Skarels break; 161330391Skarels 161430391Skarels /*---------------------------------------------------- 161530391Skarels * pass caller's programming commands to the mouse */ 161630391Skarels 161730391Skarels case QD_PRGMOUSE: 161830391Skarels 161930391Skarels duart = (struct duart *) qdmap[unit].duart; 162030391Skarels 162130391Skarels for (i = 1000; i > 0; --i) { 162230391Skarels if ((status = duart->statusB) & XMT_RDY) { 162330391Skarels duart->dataB = *datap; 162430391Skarels break; 162530391Skarels } 162630391Skarels } 162730391Skarels 162830391Skarels if (i == 0) { 162930391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [4]", unit); 163030391Skarels } 163130391Skarels 163230391Skarels break; 163330391Skarels 163430391Skarels /*---------------------------------------------- 163530391Skarels * get QDSS configuration word and return it */ 163630391Skarels 163730391Skarels case QD_RDCONFIG: 163830391Skarels 163930391Skarels *(short *)datap = qdflags[unit].config; 164030391Skarels break; 164130391Skarels 164230391Skarels /*---------------------- 164330391Skarels * program the tablet */ 164430391Skarels 164530391Skarels case QD_PRGTABLET: 164630391Skarels 164730391Skarels duart = (struct duart *) qdmap[unit].duart; 164830391Skarels 164930391Skarels for (i = 1000; i > 0; --i) { 165030391Skarels if ((status = duart->statusB) & XMT_RDY) { 165130391Skarels duart->dataB = *datap; 165230391Skarels break; 165330391Skarels } 165430391Skarels } 165530391Skarels 165630391Skarels if (i == 0) { 165730391Skarels mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [5]", unit); 165830391Skarels } 165930391Skarels 166030391Skarels break; 166130391Skarels 166230391Skarels /*----------------------------------------------- 166330391Skarels * program the tablet report resolution factor */ 166430391Skarels 166530391Skarels case QD_PRGTABRES: 166630391Skarels 166730391Skarels qdflags[unit].tab_res = *(short *)datap; 166830391Skarels break; 166930391Skarels 1670*32012Smarc #ifdef notdef 167130391Skarels case DEVIOCGET: /* device status */ 167230391Skarels devget = (struct devget *)datap; 167330391Skarels bzero(devget,sizeof(struct devget)); 167430391Skarels devget->category = DEV_TERMINAL; 167530391Skarels devget->bus = DEV_QB; 167630391Skarels bcopy(DEV_VCB02,devget->interface, 167730391Skarels strlen(DEV_VCB02)); 167830391Skarels bcopy(DEV_VR290,devget->device, 167930391Skarels strlen(DEV_VR290)); /* terminal */ 168030391Skarels devget->adpt_num = ui->ui_adpt; /* which adapter*/ 168130391Skarels devget->nexus_num = ui->ui_nexus; /* which nexus */ 168230391Skarels devget->bus_num = ui->ui_ubanum; /* which QB */ 168330391Skarels devget->ctlr_num = unit; /* which interf.*/ 168430391Skarels devget->slave_num = unit; /* which line */ 168530391Skarels bcopy(ui->ui_driver->ud_dname, 168630391Skarels devget->dev_name, 168730391Skarels strlen(ui->ui_driver->ud_dname)); /* Ultrix "qd" */ 168830391Skarels devget->unit_num = unit; /* qd line? */ 168930391Skarels devget->soft_count = 169030391Skarels sc->sc_softcnt; /* soft er. cnt.*/ 169130391Skarels devget->hard_count = 169230391Skarels sc->sc_hardcnt; /* hard er cnt. */ 169330391Skarels devget->stat = sc->sc_flags; /* status */ 169430391Skarels devget->category_stat = 169530391Skarels sc->sc_category_flags; /* cat. stat. */ 169630391Skarels break; 1697*32012Smarc #endif /* notdef */ 169830391Skarels 169930391Skarels default: 170030391Skarels /*----------------------------- 170130391Skarels * service tty type ioctl's */ 170230391Skarels 170330391Skarels if (!(minor_dev & 0x02)) { 170430391Skarels 170530391Skarels tp = &qd_tty[minor_dev]; 170630391Skarels 170730391Skarels error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); 170830391Skarels if (error >= 0) { 170930391Skarels return(error); 171030391Skarels } 171130391Skarels 171230391Skarels error = ttioctl(tp, cmd, datap, flags); 171330391Skarels if (error >= 0) { 171430391Skarels return(error); 171530391Skarels } 171630391Skarels } 171730391Skarels break; 171830391Skarels } 171930391Skarels 172030391Skarels /*-------------------------------- 172130391Skarels * clean up and get outta here */ 172230391Skarels 172330391Skarels return(0); 172430391Skarels 172530391Skarels } /* qdioctl */ 172630391Skarels 172730391Skarels /********************************************************************** 172830391Skarels * 172930391Skarels * qdselect()... service select call for event queue input 173030391Skarels * 173130391Skarels **********************************************************************/ 173230391Skarels 173330391Skarels qdselect(dev, rw) 173430391Skarels dev_t dev; 173530391Skarels int rw; 173630391Skarels { 173730391Skarels register int s; 173830391Skarels register int unit; 173930391Skarels 1740*32012Smarc s = spltty(); 174130391Skarels unit = minor(dev) >> 2; 174230391Skarels 174330391Skarels switch (rw) { 174430391Skarels 174530391Skarels case FREAD: /* event available? */ 174630391Skarels 174730391Skarels if(!(ISEMPTY(eq_header[unit]))) { 174830391Skarels splx(s); 174930391Skarels return(1); /* return "1" if event exists */ 175030391Skarels } 175130391Skarels rsel[unit] = u.u_procp; 175230391Skarels qdflags[unit].selmask |= SEL_READ; 175330391Skarels splx(s); 175430391Skarels return(0); 175530391Skarels 175630391Skarels case FWRITE: /* DMA done? */ 175730391Skarels 175830391Skarels if (DMA_ISEMPTY(DMAheader[unit])) { 175930391Skarels splx(s); 176030391Skarels return(1); /* return "1" if DMA is done */ 176130391Skarels } 176230391Skarels rsel[unit] = u.u_procp; 176330391Skarels qdflags[unit].selmask |= SEL_WRITE; 176430391Skarels splx(s); 176530391Skarels return(0); 176630391Skarels } 176730391Skarels 176830391Skarels } /* qdselect() */ 176930391Skarels 177030391Skarels /*************************************************************** 177130391Skarels * 177230391Skarels * qdwrite()... output to the QDSS screen as a TTY 177330391Skarels * 177430391Skarels ***************************************************************/ 177530391Skarels 177630391Skarels extern qd_strategy(); 177730391Skarels 177830391Skarels qdwrite(dev, uio) 177930391Skarels dev_t dev; 178030391Skarels struct uio *uio; 178130391Skarels { 178230391Skarels register struct tty *tp; 178330391Skarels register int minor_dev; 178430391Skarels register int unit; 178530391Skarels 178630391Skarels minor_dev = minor(dev); 178730391Skarels unit = (minor_dev >> 2) & 0x07; 178830391Skarels 178930391Skarels /*------------------------------ 179030391Skarels * if this is the console... */ 179130391Skarels 179230391Skarels if ((minor_dev & 0x03) != 0x02 && 179330391Skarels qdflags[unit].inuse & CONS_DEV) { 179430391Skarels tp = &qd_tty[minor_dev]; 179530391Skarels return ((*linesw[tp->t_line].l_write)(tp, uio)); 179630391Skarels } 179730391Skarels 179830391Skarels /*------------------------------------------------ 179930391Skarels * else this must be a DMA xfer from user space */ 180030391Skarels 180130391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 180230391Skarels return (physio(qd_strategy, &qdbuf[unit], 180330391Skarels dev, B_WRITE, minphys, uio)); 180430391Skarels } 180530391Skarels } 180630391Skarels 180730391Skarels /*************************************************************** 180830391Skarels * 180930391Skarels * qdread()... read from QDSS keyboard as a TTY 181030391Skarels * 181130391Skarels ***************************************************************/ 181230391Skarels 181330391Skarels qdread(dev, uio) 181430391Skarels dev_t dev; 181530391Skarels struct uio *uio; 181630391Skarels { 181730391Skarels register struct tty *tp; 181830391Skarels register int minor_dev; 181930391Skarels register int unit; 182030391Skarels 182130391Skarels minor_dev = minor(dev); 182230391Skarels unit = (minor_dev >> 2) & 0x07; 182330391Skarels 182430391Skarels /*------------------------------ 182530391Skarels * if this is the console... */ 182630391Skarels 182730391Skarels if ((minor_dev & 0x03) != 0x02 && 182830391Skarels qdflags[unit].inuse & CONS_DEV) { 182930391Skarels tp = &qd_tty[minor_dev]; 183030391Skarels return ((*linesw[tp->t_line].l_read)(tp, uio)); 183130391Skarels } 183230391Skarels 183330391Skarels /*------------------------------------------------ 183430391Skarels * else this must be a bitmap-to-processor xfer */ 183530391Skarels 183630391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 183730391Skarels return (physio(qd_strategy, &qdbuf[unit], 183830391Skarels dev, B_READ, minphys, uio)); 183930391Skarels } 184030391Skarels } 184130391Skarels 184230391Skarels /*************************************************************** 184330391Skarels * 184430391Skarels * qd_strategy()... strategy routine to do DMA 184530391Skarels * 184630391Skarels ***************************************************************/ 184730391Skarels 184830391Skarels qd_strategy(bp) 184930391Skarels register struct buf *bp; 185030391Skarels { 185130391Skarels register struct dga *dga; 185230391Skarels register struct adder *adder; 185330391Skarels 185430391Skarels char *DMAbufp; 185530391Skarels 185630391Skarels int QBAreg; 185730391Skarels int bytcnt; 185830391Skarels int s; 185930391Skarels int unit; 186030391Skarels int cookie; 186130391Skarels 186230391Skarels int i,j,k; 186330391Skarels 186430391Skarels unit = (minor(bp->b_dev) >> 2) & 0x07; 186530391Skarels 1866*32012Smarc /* 1867*32012Smarc * init pointers 1868*32012Smarc */ 186930391Skarels 187030391Skarels if ((QBAreg = ubasetup(0, bp, 0)) == 0) { 187130391Skarels mprintf("\nqd%d: qd_strategy: QBA setup error", unit); 187230391Skarels goto STRAT_ERR; 187330391Skarels } 187430391Skarels 187530391Skarels dga = (struct dga *) qdmap[unit].dga; 187630391Skarels 1877*32012Smarc s = spltty(); 187830391Skarels 187930391Skarels qdflags[unit].user_dma = -1; 188030391Skarels 188130391Skarels dga->csr |= DMA_IE; 188230391Skarels 188330391Skarels cookie = QBAreg & 0x3FFFF; 188430391Skarels dga->adrs_lo = (short) cookie; 188530391Skarels dga->adrs_hi = (short) (cookie >> 16); 188630391Skarels 188730391Skarels dga->bytcnt_lo = (short) bp->b_bcount; 188830391Skarels dga->bytcnt_hi = (short) (bp->b_bcount >> 16); 188930391Skarels 189030391Skarels while (qdflags[unit].user_dma) { 189130391Skarels sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); 189230391Skarels } 189330391Skarels 189430391Skarels splx(s); 189530391Skarels ubarelse(0, &QBAreg); 189630391Skarels 189730391Skarels if (!(dga->csr & DMA_ERR)) { 189830391Skarels iodone(bp); 189930391Skarels return; 190030391Skarels } 190130391Skarels 190230391Skarels STRAT_ERR: 190330391Skarels adder = (struct adder *) qdmap[unit].adder; 190430391Skarels adder->command = CANCEL; /* cancel adder activity */ 190530391Skarels dga->csr &= ~DMA_IE; 190630391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 190730391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 190830391Skarels bp->b_flags |= B_ERROR; /* flag an error to physio() */ 190930391Skarels 191030391Skarels /* if DMA was running, flush spurious intrpt */ 191130391Skarels 191230391Skarels if (dga->bytcnt_lo != 0) { 191330391Skarels dga->bytcnt_lo = 0; 191430391Skarels dga->bytcnt_hi = 0; 191530391Skarels DMA_SETIGNORE(DMAheader[unit]); 191630391Skarels dga->csr |= DMA_IE; 191730391Skarels } 191830391Skarels 191930391Skarels iodone(bp); 192030391Skarels 192130391Skarels } /* qd_strategy */ 192230391Skarels 192330391Skarels /******************************************************************* 192430391Skarels * 192530391Skarels * qdstart()... startup output to the console screen 192630391Skarels * 192730391Skarels ******************************************************************** 192830391Skarels * 192930391Skarels * calling convention: 193030391Skarels * 193130391Skarels * qdstart(tp); 193230391Skarels * struct tty *tp; ;pointer to tty structure 193330391Skarels * 193430391Skarels ********/ 193530391Skarels 193630391Skarels qdstart(tp) 193730391Skarels register struct tty *tp; 193830391Skarels { 193930391Skarels register int which_unit, unit, c; 194030391Skarels register struct tty *tp0; 1941*32012Smarc int needwakeup = 0; 1942*32012Smarc static int qdwakeuptime = 5; 1943*32012Smarc int wakeup(); 194430391Skarels int s; 194530391Skarels 194630391Skarels int curs_on; 194730391Skarels struct dga *dga; 194830391Skarels 194930391Skarels unit = minor(tp->t_dev); 195030391Skarels 195130391Skarels tp0 = &qd_tty[(unit & 0x0FC)+1]; 195230391Skarels which_unit = (unit >> 2) & 0x3; 195330391Skarels unit &= 0x03; 195430391Skarels 1955*32012Smarc s = spltty(); 195630391Skarels 1957*32012Smarc /* If it's currently active, or delaying, no need to do anything. */ 195830391Skarels if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 195930391Skarels goto out; 196030391Skarels 1961*32012Smarc /* 1962*32012Smarc * XXX FARKLE 1963*32012Smarc * 1964*32012Smarc * Check if the caller is going to sleep and prepare to 1965*32012Smarc * wake him up with a timeout. This is a temporary hack. 1966*32012Smarc */ 1967*32012Smarc if (tp->t_outq.c_cc > TTHIWAT(tp)) 1968*32012Smarc needwakeup++; 196930391Skarels 1970*32012Smarc /* 1971*32012Smarc * Drain the queue. 1972*32012Smarc * Drop input from anything but the console 1973*32012Smarc * device on the floor. 1974*32012Smarc */ 1975*32012Smarc 197630391Skarels while (tp->t_outq.c_cc) { 197730391Skarels c = getc(&tp->t_outq); 1978*32012Smarc if (unit == 0) 1979*32012Smarc blitc(which_unit, c & 0xFF); 198030391Skarels } 198130391Skarels 1982*32012Smarc /* 1983*32012Smarc * - FARKLE - 1984*32012Smarc * We are not a real hardware tty device that incures transmitter 1985*32012Smarc * interrupts. This breaks the paradigm used in tty.c for 1986*32012Smarc * flow control. I.e. 1987*32012Smarc * 1988*32012Smarc * spltty(); 1989*32012Smarc * ttstart(); /* schedule output which should interrupt* 1990*32012Smarc * set TT_SLEEP flag 1991*32012Smarc * sleep(outq) 1992*32012Smarc * splx(); 1993*32012Smarc * 1994*32012Smarc * Don't know what to do about this one. In the meantime we schedule 1995*32012Smarc * a wakeup for the sleep that will occur. Its gross - but works 1996*32012Smarc * for now. This will all be rewritten anyway. 1997*32012Smarc * 1998*32012Smarc */ 199930391Skarels 200030391Skarels if ( tp->t_outq.c_cc <= TTLOWAT(tp) ) { 2001*32012Smarc if (needwakeup) 2002*32012Smarc timeout(wakeup,(caddr_t)&tp->t_outq,qdwakeuptime); /*XXX*/ 200330391Skarels if (tp->t_state & TS_ASLEEP){ 200430391Skarels tp->t_state &= ~TS_ASLEEP; 200530391Skarels wakeup((caddr_t) &tp->t_outq); 2006*32012Smarc } 200730391Skarels } 200830391Skarels 200930391Skarels tp->t_state &= ~TS_BUSY; 201030391Skarels 201130391Skarels out: 201230391Skarels splx(s); 201330391Skarels 201430391Skarels } /* qdstart */ 201530391Skarels 201630391Skarels 201730391Skarels /******************************************************************* 201830391Skarels * 201930391Skarels * qdstop()... stop the tty 202030391Skarels * 202130391Skarels *******************************************************************/ 202230391Skarels 202330391Skarels qdstop(tp, flag) 202430391Skarels register struct tty *tp; 202530391Skarels int flag; 202630391Skarels { 202730391Skarels register int s; 202830391Skarels 2029*32012Smarc log(LOG_NOTICE, "*qdstop*"); 2030*32012Smarc s = spltty(); /* block intrpts during state modification */ 203130391Skarels 203230391Skarels if (tp->t_state & TS_BUSY) { 203330391Skarels if ((tp->t_state & TS_TTSTOP) == 0) { 203430391Skarels tp->t_state |= TS_FLUSH; 203530391Skarels } else 203630391Skarels tp->t_state &= ~TS_BUSY; 203730391Skarels } 203830391Skarels splx(s); 203930391Skarels } 204030391Skarels 204130391Skarels /******************************************************************* 204230391Skarels * 204330391Skarels * blitc()... output a character to the QDSS screen 204430391Skarels * 204530391Skarels ******************************************************************** 204630391Skarels * 204730391Skarels * calling convention: 204830391Skarels * 204930391Skarels * blitc(chr); 205030391Skarels * char chr; ;character to be displayed 205130391Skarels * 205230391Skarels ********/ 205330391Skarels 205430391Skarels blitc(unit, chr) 205530391Skarels int unit; 205630391Skarels char chr; 205730391Skarels { 205830391Skarels register struct adder *adder; 205930391Skarels register struct dga *dga; 206030391Skarels register int i; 2061*32012Smarc static short inescape[NQD]; 206230391Skarels 206330391Skarels short x; 206430391Skarels 2065*32012Smarc /* init stuff */ 206630391Skarels 206730391Skarels adder = (struct adder *) qdmap[unit].adder; 206830391Skarels dga = (struct dga *) qdmap[unit].dga; 206930391Skarels 207030391Skarels chr &= 0x7F; 207130391Skarels 2072*32012Smarc /* 2073*32012Smarc * Support cursor addressing so vi will work. 2074*32012Smarc * Decode for "\E=%.%." cursor motion description. 2075*32012Smarc * 2076*32012Smarc * If we've seen an escape, grab up to three more 2077*32012Smarc * characters, bailing out if necessary. 2078*32012Smarc */ 2079*32012Smarc if (inescape[unit]) { 2080*32012Smarc switch (inescape[unit]++) { 2081*32012Smarc case 1: 2082*32012Smarc if (chr != '=') { 2083*32012Smarc /* bogus escape sequence */ 2084*32012Smarc inescape[unit] = 0; 2085*32012Smarc blitc(unit, chr); 2086*32012Smarc } 2087*32012Smarc return(0); 2088*32012Smarc case 2: 2089*32012Smarc /* position row */ 2090*32012Smarc cursor[unit].y = CHAR_HEIGHT * chr; 2091*32012Smarc if (cursor[unit].y > 863 - CHAR_HEIGHT) 2092*32012Smarc cursor[unit].y = 863 - CHAR_HEIGHT; 2093*32012Smarc dga->y_cursor = TRANY(cursor[unit].y); 2094*32012Smarc return(0); 2095*32012Smarc case 3: 2096*32012Smarc /* position column */ 2097*32012Smarc cursor[unit].x = CHAR_WIDTH * chr; 2098*32012Smarc if (cursor[unit].x > 1024 - CHAR_WIDTH) 2099*32012Smarc cursor[unit].x = 1023 - CHAR_WIDTH; 2100*32012Smarc dga->x_cursor = TRANX(cursor[unit].x); 2101*32012Smarc inescape[unit] = 0; 2102*32012Smarc return(0); 2103*32012Smarc default: 2104*32012Smarc inescape[unit] = 0; 2105*32012Smarc blitc(unit, chr); 2106*32012Smarc } 2107*32012Smarc } 2108*32012Smarc 2109*32012Smarc 211030391Skarels switch (chr) { 211130391Skarels 211230391Skarels case '\r': /* return char */ 211330391Skarels cursor[unit].x = 0; 211430391Skarels dga->x_cursor = TRANX(cursor[unit].x); 211530391Skarels return(0); 211630391Skarels 211730391Skarels case '\t': /* tab char */ 211830391Skarels 211930391Skarels for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) { 212030391Skarels blitc(unit, ' '); 212130391Skarels } 212230391Skarels return(0); 212330391Skarels 212430391Skarels case '\n': /* line feed char */ 212530391Skarels 212630391Skarels if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { 212730391Skarels if (qdflags[unit].inuse & GRAPHIC_DEV) { 212830391Skarels cursor[unit].y = 0; 212930391Skarels } else { 213030391Skarels cursor[unit].y -= CHAR_HEIGHT; 213130391Skarels scroll_up(adder); 213230391Skarels } 213330391Skarels } 213430391Skarels dga->y_cursor = TRANY(cursor[unit].y); 213530391Skarels return(0); 213630391Skarels 213730391Skarels case '\b': /* backspace char */ 213830391Skarels if (cursor[unit].x > 0) { 2139*32012Smarc /**** - REMOVED - CRTBS is a function of the line discipline 214030391Skarels cursor[unit].x -= CHAR_WIDTH; 214130391Skarels blitc(unit, ' '); 2142*32012Smarc ****/ 214330391Skarels cursor[unit].x -= CHAR_WIDTH; 214430391Skarels dga->x_cursor = TRANX(cursor[unit].x); 214530391Skarels } 214630391Skarels return(0); 214730391Skarels 2148*32012Smarc case CTRL(k): /* cursor up */ 2149*32012Smarc if (cursor[unit].y > 0) { 2150*32012Smarc cursor[unit].y -= CHAR_HEIGHT; 2151*32012Smarc dga->y_cursor = TRANY(cursor[unit].y); 2152*32012Smarc } 2153*32012Smarc return(0); 2154*32012Smarc 2155*32012Smarc case CTRL(^): /* home cursor */ 2156*32012Smarc cursor[unit].x = 0; 2157*32012Smarc dga->x_cursor = TRANX(cursor[unit].x); 2158*32012Smarc cursor[unit].y = 0; 2159*32012Smarc dga->y_cursor = TRANY(cursor[unit].y); 2160*32012Smarc return(0); 2161*32012Smarc 2162*32012Smarc case CTRL(l): /* cursor right */ 2163*32012Smarc if (cursor[unit].x < 1023 - CHAR_WIDTH) { 2164*32012Smarc cursor[unit].x += CHAR_WIDTH; 2165*32012Smarc dga->x_cursor = TRANX(cursor[unit].x); 2166*32012Smarc } 2167*32012Smarc return(0); 2168*32012Smarc 2169*32012Smarc case CTRL(z): /* clear screen */ 2170*32012Smarc setup_dragon(unit); 2171*32012Smarc clear_qd_screen(unit); 2172*32012Smarc /* and home cursor - termcap seems to assume this */ 2173*32012Smarc cursor[unit].x = 0; 2174*32012Smarc dga->x_cursor = TRANX(cursor[unit].x); 2175*32012Smarc cursor[unit].y = 0; 2176*32012Smarc dga->y_cursor = TRANY(cursor[unit].y); 2177*32012Smarc return(0); 2178*32012Smarc 2179*32012Smarc case '\033': /* start escape sequence */ 2180*32012Smarc inescape[unit] = 1; 2181*32012Smarc return(0); 2182*32012Smarc 218330391Skarels default: 218430391Skarels if (chr < ' ' || chr > '~') 218530391Skarels return(0); 218630391Skarels } 218730391Skarels 2188*32012Smarc /* setup VIPER operand control registers */ 218930391Skarels 219030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ 219130391Skarels write_ID(adder, SRC1_OCR_B, 219230391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 219330391Skarels 219430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ 219530391Skarels write_ID(adder, SRC1_OCR_B, 219630391Skarels EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); 219730391Skarels 219830391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 219930391Skarels write_ID(adder, DST_OCR_B, 220030391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 220130391Skarels 220230391Skarels write_ID(adder, MASK_1, 0xFFFF); 220330391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); 220430391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 220530391Skarels 2206*32012Smarc /* load DESTINATION origin and vectors */ 220730391Skarels 220830391Skarels adder->fast_dest_dy = 0; 220930391Skarels adder->slow_dest_dx = 0; 221030391Skarels adder->error_1 = 0; 221130391Skarels adder->error_2 = 0; 221230391Skarels 221330391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 221430391Skarels 221530391Skarels wait_status(adder, RASTEROP_COMPLETE); 221630391Skarels 221730391Skarels adder->destination_x = cursor[unit].x; 221830391Skarels adder->fast_dest_dx = CHAR_WIDTH; 221930391Skarels 222030391Skarels adder->destination_y = cursor[unit].y; 222130391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 222230391Skarels 2223*32012Smarc /* load SOURCE origin and vectors */ 222430391Skarels 222530391Skarels adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH); 222630391Skarels adder->source_1_y = FONT_Y; 222730391Skarels 222830391Skarels adder->source_1_dx = CHAR_WIDTH; 222930391Skarels adder->source_1_dy = CHAR_HEIGHT; 223030391Skarels 223130391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 223230391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 223330391Skarels 2234*32012Smarc /* update console cursor coordinates */ 223530391Skarels 223630391Skarels cursor[unit].x += CHAR_WIDTH; 223730391Skarels dga->x_cursor = TRANX(cursor[unit].x); 223830391Skarels 2239*32012Smarc /* auto-wrap margin */ 224030391Skarels if (cursor[unit].x > (1024 - CHAR_WIDTH)) { 224130391Skarels blitc(unit, '\r'); 224230391Skarels blitc(unit, '\n'); 224330391Skarels } 224430391Skarels 224530391Skarels } /* blitc */ 224630391Skarels 224730391Skarels qdreset(){} 224830391Skarels qd_init(){} 224930391Skarels 225030391Skarels /****************************************************************** 225130391Skarels * 225230391Skarels * INTERRUPT SERVICE ROUTINES START HERE: 225330391Skarels * 225430391Skarels ******************************************************************/ 225530391Skarels 225630391Skarels /***************************************************************** 225730391Skarels * 225830391Skarels * qddint()... service "DMA DONE" interrupt condition 225930391Skarels * 226030391Skarels *****************************************************************/ 226130391Skarels 226230391Skarels qddint(qd) 226330391Skarels int qd; 226430391Skarels { 226530391Skarels register struct DMAreq_header *header; 226630391Skarels register struct DMAreq *request; 226730391Skarels register struct dga *dga; 226830391Skarels struct adder *adder; 226930391Skarels 227030391Skarels int cookie; /* DMA adrs for QDSS */ 227130391Skarels int i; 227230391Skarels 227330391Skarels spl4(); /* allow interval timer in */ 227430391Skarels 2275*32012Smarc /* 2276*32012Smarc * init pointers 2277*32012Smarc */ 227830391Skarels 227930391Skarels header = DMAheader[qd]; /* register for optimization */ 228030391Skarels dga = (struct dga *) qdmap[qd].dga; 228130391Skarels adder = (struct adder *) qdmap[qd].adder; 228230391Skarels 2283*32012Smarc /* 2284*32012Smarc * if this interrupt flagged as bogus for interrupt flushing purposes.. 2285*32012Smarc */ 228630391Skarels 228730391Skarels if (DMA_ISIGNORE(header)) { 228830391Skarels DMA_CLRIGNORE(header); 228930391Skarels return; 229030391Skarels } 229130391Skarels 229230391Skarels /*---------------------------------------------------- 229330391Skarels * dump a DMA hardware error message if appropriate */ 229430391Skarels 229530391Skarels if (dga->csr & DMA_ERR) { 229630391Skarels 229730391Skarels if (dga->csr & PARITY_ERR) 229830391Skarels mprintf("\nqd%d: qddint: DMA hardware parity fault.", qd); 229930391Skarels 230030391Skarels if (dga->csr & BUS_ERR) 230130391Skarels mprintf("\nqd%d: qddint: DMA hardware bus error.", qd); 230230391Skarels } 230330391Skarels 230430391Skarels /*---------------------------------------- 230530391Skarels * if this was a DMA from user space... */ 230630391Skarels 230730391Skarels if (qdflags[qd].user_dma) { 230830391Skarels qdflags[qd].user_dma = 0; 230930391Skarels wakeup((caddr_t)&qdflags[qd].user_dma); 231030391Skarels return; 231130391Skarels } 231230391Skarels 231330391Skarels /*------------------------------------------------------------------------ 231430391Skarels * if we're doing DMA request queue services, field the error condition */ 231530391Skarels 231630391Skarels if (dga->csr & DMA_ERR) { 231730391Skarels 231830391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 231930391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 232030391Skarels adder->command = CANCEL; /* cancel adder activity */ 232130391Skarels 232230391Skarels DMA_SETERROR(header); /* flag error in header status word */ 232330391Skarels DMA_CLRACTIVE(header); 232430391Skarels header->DMAreq[header->oldest].DMAdone |= HARD_ERROR; 232530391Skarels header->newest = header->oldest; 232630391Skarels header->used = 0; 232730391Skarels 232830391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 232930391Skarels selwakeup(rsel[qd], 0); 233030391Skarels rsel[qd] = 0; 233130391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 233230391Skarels } 233330391Skarels 233430391Skarels if (dga->bytcnt_lo != 0) { 233530391Skarels dga->bytcnt_lo = 0; 233630391Skarels dga->bytcnt_hi = 0; 233730391Skarels DMA_SETIGNORE(header); 233830391Skarels } 233930391Skarels 234030391Skarels return; 234130391Skarels } 234230391Skarels 234330391Skarels /*---------------------------------------------------------------------------- 234430391Skarels * if the DMA request queue is now becoming non-full, wakeup "select" client */ 234530391Skarels 234630391Skarels if (DMA_ISFULL(header)) { 234730391Skarels 234830391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 234930391Skarels selwakeup(rsel[qd], 0); 235030391Skarels rsel[qd] = 0; 235130391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 235230391Skarels } 235330391Skarels } 235430391Skarels 235530391Skarels header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE; 235630391Skarels 235730391Skarels if (DMA_ISEMPTY(header)) { 235830391Skarels mprintf("\nqd%d: qddint: unexpected interrupt", qd); 235930391Skarels return; 236030391Skarels } 236130391Skarels 236230391Skarels DMA_GETEND(header); /* update request queue indices */ 236330391Skarels 236430391Skarels /*------------------------------------------------------------ 236530391Skarels * if no more DMA pending, wake up "select" client and exit */ 236630391Skarels 236730391Skarels if (DMA_ISEMPTY(header)) { 236830391Skarels 236930391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 237030391Skarels selwakeup(rsel[qd], 0); 237130391Skarels rsel[qd] = 0; 237230391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 237330391Skarels } 237430391Skarels 237530391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 237630391Skarels return; 237730391Skarels } 237830391Skarels 237930391Skarels /*--------------------------- 238030391Skarels * initiate next DMA xfer */ 238130391Skarels 238230391Skarels request = DMA_GETBEGIN(header); 238330391Skarels 238430391Skarels switch (request->DMAtype) { 238530391Skarels 238630391Skarels case DISPLIST: 238730391Skarels dga->csr |= DL_ENB; 238830391Skarels break; 238930391Skarels 239030391Skarels case PTOB: 239130391Skarels dga->csr |= PTOB_ENB; 239230391Skarels break; 239330391Skarels 239430391Skarels case BTOP: 239530391Skarels dga->csr |= BTOP_ENB; 239630391Skarels break; 239730391Skarels 239830391Skarels default: 239930391Skarels mprintf("\nqd%d: qddint: illegal DMAtype parameter.", qd); 240030391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 240130391Skarels return; 240230391Skarels } 240330391Skarels 240430391Skarels if (request->DMAdone & COUNT_ZERO) { 240530391Skarels dga->csr &= ~SET_DONE_FIFO; 240630391Skarels } else if (request->DMAdone & FIFO_EMPTY) { 240730391Skarels dga->csr |= SET_DONE_FIFO; 240830391Skarels } 240930391Skarels 241030391Skarels if (request->DMAdone & WORD_PACK) 241130391Skarels dga->csr &= ~BYTE_DMA; 241230391Skarels else if (request->DMAdone & BYTE_PACK) 241330391Skarels dga->csr |= BYTE_DMA; 241430391Skarels 241530391Skarels dga->csr |= DMA_IE; 241630391Skarels 241730391Skarels cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg; 241830391Skarels 241930391Skarels dga->adrs_lo = (short) cookie; 242030391Skarels dga->adrs_hi = (short) (cookie >> 16); 242130391Skarels 242230391Skarels dga->bytcnt_lo = (short) request->length; 242330391Skarels dga->bytcnt_hi = (short) (request->length >> 16); 242430391Skarels 242530391Skarels return; 242630391Skarels } 242730391Skarels 242830391Skarels /***************************************************************** 242930391Skarels * 243030391Skarels * qdaint()... ADDER interrupt service 243130391Skarels * 243230391Skarels *****************************************************************/ 243330391Skarels 243430391Skarels qdaint(qd) 243530391Skarels register int qd; 243630391Skarels { 243730391Skarels register struct adder *adder; 243830391Skarels struct color_buf *cbuf; 243930391Skarels 244030391Skarels short stat; 244130391Skarels int i; 244230391Skarels register struct rgb *rgbp; 244330391Skarels register short *red; 244430391Skarels register short *green; 244530391Skarels register short *blue; 244630391Skarels 244730391Skarels spl4(); /* allow interval timer in */ 244830391Skarels 244930391Skarels adder = (struct adder *) qdmap[qd].adder; 245030391Skarels 245130391Skarels /*------------------------------------------------------------------------ 245230391Skarels * service the vertical blank interrupt (VSYNC bit) by loading any pending 245330391Skarels * color map load request */ 245430391Skarels 245530391Skarels if (adder->status & VSYNC) { 245630391Skarels adder->status &= ~VSYNC; /* clear the interrupt */ 245730391Skarels 245830391Skarels cbuf = color_buf[qd]; 245930391Skarels if (cbuf->status & LOAD_COLOR_MAP) { 246030391Skarels 246130391Skarels red = (short *) qdmap[qd].red; 246230391Skarels green = (short *) qdmap[qd].green; 246330391Skarels blue = (short *) qdmap[qd].blue; 246430391Skarels 246530391Skarels for (i = cbuf->count, rgbp = cbuf->rgb; --i >= 0; rgbp++) { 246630391Skarels 246730391Skarels red[rgbp->offset] = (short) rgbp->red; 246830391Skarels green[rgbp->offset] = (short) rgbp->green; 246930391Skarels blue[rgbp->offset] = (short) rgbp->blue; 247030391Skarels } 247130391Skarels 247230391Skarels cbuf->status &= ~LOAD_COLOR_MAP; 247330391Skarels } 247430391Skarels } 247530391Skarels 247630391Skarels /*------------------------------------------------- 247730391Skarels * service the scroll interrupt (FRAME_SYNC bit) */ 247830391Skarels 247930391Skarels if (adder->status & FRAME_SYNC) { 248030391Skarels adder->status &= ~FRAME_SYNC; /* clear the interrupt */ 248130391Skarels 248230391Skarels if (scroll[qd]->status & LOAD_REGS) { 248330391Skarels 248430391Skarels for ( i = 1000, adder->status = 0 248530391Skarels ; i > 0 && !((stat = adder->status) & ID_SCROLL_READY) 248630391Skarels ; --i); 248730391Skarels 248830391Skarels if (i == 0) { 248930391Skarels mprintf("\nqd%d: qdaint: timeout on ID_SCROLL_READY", qd); 249030391Skarels return; 249130391Skarels } 249230391Skarels 249330391Skarels adder->ID_scroll_data = scroll[qd]->viper_constant; 249430391Skarels adder->ID_scroll_command = ID_LOAD | SCROLL_CONSTANT; 249530391Skarels 249630391Skarels adder->y_scroll_constant = scroll[qd]->y_scroll_constant; 249730391Skarels adder->y_offset_pending = scroll[qd]->y_offset; 249830391Skarels 249930391Skarels if (scroll[qd]->status & LOAD_INDEX) { 250030391Skarels 250130391Skarels adder->x_index_pending = scroll[qd]->x_index_pending; 250230391Skarels adder->y_index_pending = scroll[qd]->y_index_pending; 250330391Skarels } 250430391Skarels 250530391Skarels scroll[qd]->status = 0x00; 250630391Skarels } 250730391Skarels } 250830391Skarels } 250930391Skarels 251030391Skarels /***************************************************************** 251130391Skarels * 251230391Skarels * qdiint()... DUART input interrupt service routine 251330391Skarels * 251430391Skarels *****************************************************************/ 251530391Skarels 251630391Skarels qdiint(qd) 251730391Skarels register int qd; 251830391Skarels { 251930391Skarels register struct _vs_event *event; 252030391Skarels register struct qdinput *eqh; 252130391Skarels 252230391Skarels struct dga *dga; 252330391Skarels struct duart *duart; 252430391Skarels struct mouse_report *new_rep; 252530391Skarels 252630391Skarels struct uba_device *ui; 252730391Skarels struct tty *tp; 252830391Skarels 252930391Skarels char chr; 253030391Skarels int i,j; 253130391Skarels int k,l; 253230391Skarels 253330391Skarels u_short status; 253430391Skarels u_short data; 253530391Skarels u_short key; 253630391Skarels 253730391Skarels char do_wakeup = 0; /* flag to do a select wakeup call */ 253830391Skarels char a, b, c; /* mouse button test variables */ 253930391Skarels 254030391Skarels spl4(); /* allow interval timer in */ 254130391Skarels 254230391Skarels eqh = eq_header[qd]; /* optimized as a register */ 254330391Skarels new_rep = ¤t_rep[qd]; 254430391Skarels duart = (struct duart *) qdmap[qd].duart; 254530391Skarels 254630391Skarels /*----------------------------------------- 254730391Skarels * if the graphic device is turned on.. */ 254830391Skarels 254930391Skarels if (qdflags[qd].inuse & GRAPHIC_DEV) { 255030391Skarels 255130391Skarels /*--------------- 255230391Skarels * empty DUART */ 255330391Skarels 255430391Skarels while ((status = duart->statusA) & RCV_RDY || 255530391Skarels (status = duart->statusB) & RCV_RDY) { 255630391Skarels 255730391Skarels /*--------------------------------- 255830391Skarels * pick up LK-201 input (if any) */ 255930391Skarels 256030391Skarels if ((status = duart->statusA) & RCV_RDY) { 256130391Skarels 256230391Skarels /* if error condition, then reset it */ 256330391Skarels 256430391Skarels if ((status = duart->statusA) & 0x70) { 256530391Skarels duart->cmdA = 0x40; 256630391Skarels continue; 256730391Skarels } 256830391Skarels 256930391Skarels /* event queue full now? (overflow condition) */ 257030391Skarels 257130391Skarels if (ISFULL(eqh) == TRUE) { 257230391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 257330391Skarels break; 257430391Skarels } 257530391Skarels 257630391Skarels /*-------------------------------------- 257730391Skarels * Check for various keyboard errors */ 257830391Skarels 257930391Skarels key = duart->dataA & 0xFF; 258030391Skarels 258130391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 258230391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 258330391Skarels mprintf("\nqd%d: qdiint: keyboard error, code = %x",qd,key); 258430391Skarels return(0); 258530391Skarels } 258630391Skarels 258730391Skarels if (key < LK_LOWEST) 258830391Skarels return(0); 258930391Skarels 259030391Skarels ++do_wakeup; /* request a select wakeup call */ 259130391Skarels 259230391Skarels event = PUTBEGIN(eqh); 259330391Skarels PUTEND(eqh); 259430391Skarels 259530391Skarels event->vse_key = key; 259630391Skarels event->vse_key &= 0x00FF; 259730391Skarels event->vse_x = eqh->curs_pos.x; 259830391Skarels event->vse_y = eqh->curs_pos.y; 259930391Skarels event->vse_time = TOY; 260030391Skarels event->vse_type = VSE_BUTTON; 260130391Skarels event->vse_direction = VSE_KBTRAW; 260230391Skarels event->vse_device = VSE_DKB; 260330391Skarels } 260430391Skarels 260530391Skarels /*------------------------------------- 260630391Skarels * pick up the mouse input (if any) */ 260730391Skarels 260830391Skarels if ((status = duart->statusB) & RCV_RDY && 260930391Skarels qdflags[qd].pntr_id == MOUSE_ID) { 261030391Skarels 261130391Skarels if (status & 0x70) { 261230391Skarels duart->cmdB = 0x40; 261330391Skarels continue; 261430391Skarels } 261530391Skarels 261630391Skarels /* event queue full now? (overflow condition) */ 261730391Skarels 261830391Skarels if (ISFULL(eqh) == TRUE) { 261930391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 262030391Skarels break; 262130391Skarels } 262230391Skarels 262330391Skarels data = duart->dataB; /* get report byte */ 262430391Skarels ++new_rep->bytcnt; /* bump report byte count */ 262530391Skarels 262630391Skarels /*--------------------------- 262730391Skarels * if 1st byte of report.. */ 262830391Skarels 262930391Skarels if ( data & START_FRAME) { 263030391Skarels new_rep->state = data; 263130391Skarels if (new_rep->bytcnt > 1) { 263230391Skarels new_rep->bytcnt = 1; /* start of new frame */ 263330391Skarels continue; /* ..continue looking */ 263430391Skarels } 263530391Skarels } 263630391Skarels 263730391Skarels /*--------------------------- 263830391Skarels * if 2nd byte of report.. */ 263930391Skarels 264030391Skarels else if (new_rep->bytcnt == 2) { 264130391Skarels new_rep->dx = data & 0x00FF; 264230391Skarels } 264330391Skarels 264430391Skarels /*------------------------------------------------- 264530391Skarels * if 3rd byte of report, load input event queue */ 264630391Skarels 264730391Skarels else if (new_rep->bytcnt == 3) { 264830391Skarels 264930391Skarels new_rep->dy = data & 0x00FF; 265030391Skarels new_rep->bytcnt = 0; 265130391Skarels 265230391Skarels /*----------------------------------- 265330391Skarels * if mouse position has changed.. */ 265430391Skarels 265530391Skarels if (new_rep->dx != 0 || new_rep->dy != 0) { 265630391Skarels 265730391Skarels /*--------------------------------------------- 265830391Skarels * calculate acceleration factor, if needed */ 265930391Skarels 266030391Skarels if (qdflags[qd].curs_acc > ACC_OFF) { 266130391Skarels 266230391Skarels if (qdflags[qd].curs_thr <= new_rep->dx) 266330391Skarels new_rep->dx += 266430391Skarels (new_rep->dx - qdflags[qd].curs_thr) 266530391Skarels * qdflags[qd].curs_acc; 266630391Skarels 266730391Skarels if (qdflags[qd].curs_thr <= new_rep->dy) 266830391Skarels new_rep->dy += 266930391Skarels (new_rep->dy - qdflags[qd].curs_thr) 267030391Skarels * qdflags[qd].curs_acc; 267130391Skarels } 267230391Skarels 267330391Skarels /*------------------------------------- 267430391Skarels * update cursor position coordinates */ 267530391Skarels 267630391Skarels if (new_rep->state & X_SIGN) { 267730391Skarels eqh->curs_pos.x += new_rep->dx; 267830391Skarels if (eqh->curs_pos.x > 1023) 267930391Skarels eqh->curs_pos.x = 1023; 268030391Skarels } 268130391Skarels else { 268230391Skarels eqh->curs_pos.x -= new_rep->dx; 268330391Skarels if (eqh->curs_pos.x < -15) 268430391Skarels eqh->curs_pos.x = -15; 268530391Skarels } 268630391Skarels 268730391Skarels if (new_rep->state & Y_SIGN) { 268830391Skarels eqh->curs_pos.y -= new_rep->dy; 268930391Skarels if (eqh->curs_pos.y < -15) 269030391Skarels eqh->curs_pos.y = -15; 269130391Skarels } 269230391Skarels else { 269330391Skarels eqh->curs_pos.y += new_rep->dy; 269430391Skarels if (eqh->curs_pos.y > 863) 269530391Skarels eqh->curs_pos.y = 863; 269630391Skarels } 269730391Skarels 269830391Skarels /*--------------------------------- 269930391Skarels * update cursor screen position */ 270030391Skarels 270130391Skarels dga = (struct dga *) qdmap[qd].dga; 270230391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 270330391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 270430391Skarels 270530391Skarels /*-------------------------------------------- 270630391Skarels * if cursor is in the box, no event report */ 270730391Skarels 270830391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 270930391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 271030391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 271130391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 271230391Skarels goto GET_MBUTTON; 271330391Skarels } 271430391Skarels 271530391Skarels /*--------------------------------- 271630391Skarels * report the mouse motion event */ 271730391Skarels 271830391Skarels event = PUTBEGIN(eqh); 271930391Skarels PUTEND(eqh); 272030391Skarels 272130391Skarels ++do_wakeup; /* request a select wakeup call */ 272230391Skarels 272330391Skarels event->vse_x = eqh->curs_pos.x; 272430391Skarels event->vse_y = eqh->curs_pos.y; 272530391Skarels 272630391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 272730391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 272830391Skarels event->vse_key = 0; 272930391Skarels event->vse_direction = 0; 273030391Skarels event->vse_time = TOY; /* time stamp */ 273130391Skarels } 273230391Skarels 273330391Skarels GET_MBUTTON: 273430391Skarels /*------------------------------- 273530391Skarels * if button state has changed */ 273630391Skarels 273730391Skarels a = new_rep->state & 0x07; /*mask nonbutton bits */ 273830391Skarels b = last_rep[qd].state & 0x07; 273930391Skarels 274030391Skarels if (a ^ b) { 274130391Skarels 274230391Skarels for ( c = 1; c < 8; c <<= 1) { 274330391Skarels 274430391Skarels if (!( c & (a ^ b))) /* this button change? */ 274530391Skarels continue; 274630391Skarels 274730391Skarels /* event queue full? (overflow condition) */ 274830391Skarels 274930391Skarels if (ISFULL(eqh) == TRUE) { 275030391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 275130391Skarels break; 275230391Skarels } 275330391Skarels 275430391Skarels event = PUTBEGIN(eqh); /* get new event */ 275530391Skarels PUTEND(eqh); 275630391Skarels 275730391Skarels ++do_wakeup; /* request select wakeup */ 275830391Skarels 275930391Skarels event->vse_x = eqh->curs_pos.x; 276030391Skarels event->vse_y = eqh->curs_pos.y; 276130391Skarels 276230391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 276330391Skarels event->vse_type = VSE_BUTTON; /* new button */ 276430391Skarels event->vse_time = TOY; /* time stamp */ 276530391Skarels 276630391Skarels /* flag changed button and if up or down */ 276730391Skarels 276830391Skarels if (c == RIGHT_BUTTON) 276930391Skarels event->vse_key = VSE_RIGHT_BUTTON; 277030391Skarels else if (c == MIDDLE_BUTTON) 277130391Skarels event->vse_key = VSE_MIDDLE_BUTTON; 277230391Skarels else if (c == LEFT_BUTTON) 277330391Skarels event->vse_key = VSE_LEFT_BUTTON; 277430391Skarels 277530391Skarels /* set bit = button depressed */ 277630391Skarels 277730391Skarels if (c & a) 277830391Skarels event->vse_direction = VSE_KBTDOWN; 277930391Skarels else 278030391Skarels event->vse_direction = VSE_KBTUP; 278130391Skarels } 278230391Skarels } 278330391Skarels 278430391Skarels /* refresh last report */ 278530391Skarels 278630391Skarels last_rep[qd] = current_rep[qd]; 278730391Skarels 278830391Skarels } /* get last byte of report */ 278930391Skarels } /* pickup mouse input */ 279030391Skarels 279130391Skarels /*-------------------------------- 279230391Skarels * pickup tablet input, if any */ 279330391Skarels 279430391Skarels else if ((status = duart->statusB) & RCV_RDY && 279530391Skarels qdflags[qd].pntr_id == TABLET_ID) { 279630391Skarels 279730391Skarels if (status & 0x70) { 279830391Skarels duart->cmdB = 0x40; 279930391Skarels continue; 280030391Skarels } 280130391Skarels 280230391Skarels /* event queue full now? (overflow condition) */ 280330391Skarels 280430391Skarels if (ISFULL(eqh) == TRUE) { 280530391Skarels mprintf("\nqd%d: qdiint: event queue overflow", qd); 280630391Skarels break; 280730391Skarels } 280830391Skarels 280930391Skarels data = duart->dataB; /* get report byte */ 281030391Skarels ++new_rep->bytcnt; /* bump report byte count */ 281130391Skarels 281230391Skarels /*--------------------------- 281330391Skarels * if 1st byte of report.. */ 281430391Skarels 281530391Skarels if (data & START_FRAME) { 281630391Skarels new_rep->state = data; 281730391Skarels if (new_rep->bytcnt > 1) { 281830391Skarels new_rep->bytcnt = 1; /* start of new frame */ 281930391Skarels continue; /* ..continue looking */ 282030391Skarels } 282130391Skarels } 282230391Skarels 282330391Skarels /*--------------------------- 282430391Skarels * if 2nd byte of report.. */ 282530391Skarels 282630391Skarels else if (new_rep->bytcnt == 2) { 282730391Skarels new_rep->dx = data & 0x3F; 282830391Skarels } 282930391Skarels 283030391Skarels /*--------------------------- 283130391Skarels * if 3rd byte of report.. */ 283230391Skarels 283330391Skarels else if (new_rep->bytcnt == 3) { 283430391Skarels new_rep->dx |= (data & 0x3F) << 6; 283530391Skarels } 283630391Skarels 283730391Skarels /*--------------------------- 283830391Skarels * if 4th byte of report.. */ 283930391Skarels 284030391Skarels else if (new_rep->bytcnt == 4) { 284130391Skarels new_rep->dy = data & 0x3F; 284230391Skarels } 284330391Skarels 284430391Skarels /*------------------------------------------------- 284530391Skarels * if 5th byte of report, load input event queue */ 284630391Skarels 284730391Skarels else if (new_rep->bytcnt == 5) { 284830391Skarels 284930391Skarels new_rep->dy |= (data & 0x3F) << 6; 285030391Skarels new_rep->bytcnt = 0; 285130391Skarels 285230391Skarels /*------------------------------------- 285330391Skarels * update cursor position coordinates */ 285430391Skarels 285530391Skarels new_rep->dx /= qdflags[qd].tab_res; 285630391Skarels new_rep->dy = (2200 - new_rep->dy) 285730391Skarels / qdflags[qd].tab_res; 285830391Skarels 285930391Skarels if (new_rep->dx > 1023) { 286030391Skarels new_rep->dx = 1023; 286130391Skarels } 286230391Skarels if (new_rep->dy > 863) { 286330391Skarels new_rep->dy = 863; 286430391Skarels } 286530391Skarels 286630391Skarels /* 286730391Skarels * report an event if the puck/stylus has moved 286830391Skarels */ 286930391Skarels 287030391Skarels if (eqh->curs_pos.x != new_rep->dx || 287130391Skarels eqh->curs_pos.y != new_rep->dy) { 287230391Skarels 287330391Skarels eqh->curs_pos.x = new_rep->dx; 287430391Skarels eqh->curs_pos.y = new_rep->dy; 287530391Skarels 287630391Skarels /*--------------------------------- 287730391Skarels * update cursor screen position */ 287830391Skarels 287930391Skarels dga = (struct dga *) qdmap[qd].dga; 288030391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 288130391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 288230391Skarels 288330391Skarels /* 288430391Skarels * if cursor is in the box, no event report 288530391Skarels */ 288630391Skarels 288730391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 288830391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 288930391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 289030391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 289130391Skarels goto GET_TBUTTON; 289230391Skarels } 289330391Skarels 289430391Skarels /*--------------------------------- 289530391Skarels * report the tablet motion event */ 289630391Skarels 289730391Skarels event = PUTBEGIN(eqh); 289830391Skarels PUTEND(eqh); 289930391Skarels 290030391Skarels ++do_wakeup; /* request a select wakeup call */ 290130391Skarels 290230391Skarels event->vse_x = eqh->curs_pos.x; 290330391Skarels event->vse_y = eqh->curs_pos.y; 290430391Skarels 290530391Skarels event->vse_device = VSE_TABLET; /* tablet */ 290630391Skarels /* 290730391Skarels * right now, X handles tablet motion the same 290830391Skarels * as mouse motion 290930391Skarels */ 291030391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 291130391Skarels event->vse_key = 0; 291230391Skarels event->vse_direction = 0; 291330391Skarels event->vse_time = TOY; /* time stamp */ 291430391Skarels } 291530391Skarels GET_TBUTTON: 291630391Skarels /*------------------------------- 291730391Skarels * if button state has changed */ 291830391Skarels 291930391Skarels a = new_rep->state & 0x1E; /* mask nonbutton bits */ 292030391Skarels b = last_rep[qd].state & 0x1E; 292130391Skarels 292230391Skarels if (a ^ b) { 292330391Skarels 292430391Skarels /* event queue full now? (overflow condition) */ 292530391Skarels 292630391Skarels if (ISFULL(eqh) == TRUE) { 292730391Skarels mprintf("\nqd%d: qdiint: event queue overflow",qd); 292830391Skarels break; 292930391Skarels } 293030391Skarels 293130391Skarels event = PUTBEGIN(eqh); /* get new event */ 293230391Skarels PUTEND(eqh); 293330391Skarels 293430391Skarels ++do_wakeup; /* request a select wakeup call */ 293530391Skarels 293630391Skarels event->vse_x = eqh->curs_pos.x; 293730391Skarels event->vse_y = eqh->curs_pos.y; 293830391Skarels 293930391Skarels event->vse_device = VSE_TABLET; /* tablet */ 294030391Skarels event->vse_type = VSE_BUTTON; /* button changed */ 294130391Skarels event->vse_time = TOY; /* time stamp */ 294230391Skarels 294330391Skarels /* define the changed button and if up or down */ 294430391Skarels 294530391Skarels for ( c = 1; c <= 0x10; c <<= 1) { 294630391Skarels if (c & (a ^ b)) { 294730391Skarels if (c == T_LEFT_BUTTON) 294830391Skarels event->vse_key = VSE_T_LEFT_BUTTON; 294930391Skarels else if (c == T_FRONT_BUTTON) 295030391Skarels event->vse_key = VSE_T_FRONT_BUTTON; 295130391Skarels else if (c == T_RIGHT_BUTTON) 295230391Skarels event->vse_key = VSE_T_RIGHT_BUTTON; 295330391Skarels else if (c == T_BACK_BUTTON) 295430391Skarels event->vse_key = VSE_T_BACK_BUTTON; 295530391Skarels break; 295630391Skarels } 295730391Skarels } 295830391Skarels 295930391Skarels /* set bit = button depressed */ 296030391Skarels 296130391Skarels if (c & a) 296230391Skarels event->vse_direction = VSE_KBTDOWN; 296330391Skarels else 296430391Skarels event->vse_direction = VSE_KBTUP; 296530391Skarels } 296630391Skarels 296730391Skarels /* refresh last report */ 296830391Skarels 296930391Skarels last_rep[qd] = current_rep[qd]; 297030391Skarels 297130391Skarels } /* get last byte of report */ 297230391Skarels } /* pick up tablet input */ 297330391Skarels 297430391Skarels } /* while input available.. */ 297530391Skarels 297630391Skarels /*--------------------- 297730391Skarels * do select wakeup */ 297830391Skarels 297930391Skarels if (rsel[qd] && do_wakeup && qdflags[qd].selmask & SEL_READ) { 298030391Skarels selwakeup(rsel[qd], 0); 298130391Skarels rsel[qd] = 0; 298230391Skarels qdflags[qd].selmask &= ~SEL_READ; 298330391Skarels do_wakeup = 0; 298430391Skarels } 298530391Skarels } 298630391Skarels 298730391Skarels /*----------------------------------------------------------------- 298830391Skarels * if the graphic device is not turned on, this is console input */ 298930391Skarels 299030391Skarels else { 299130391Skarels 299230391Skarels ui = qdinfo[qd]; 299330391Skarels if (ui == 0 || ui->ui_alive == 0) 299430391Skarels return(0); 299530391Skarels 299630391Skarels tp = &qd_tty[qd << 2]; 299730391Skarels 299830391Skarels /*-------------------------------------- 299930391Skarels * Get a character from the keyboard. */ 300030391Skarels 300130391Skarels while ((status = duart->statusA) & RCV_RDY) { 300230391Skarels 300330391Skarels key = duart->dataA; 300430391Skarels key &= 0xFF; 300530391Skarels 300630391Skarels /*-------------------------------------- 300730391Skarels * Check for various keyboard errors */ 300830391Skarels 300930391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 301030391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 301130391Skarels mprintf("\nqd%d: qdiint: Keyboard error, code = %x",qd,key); 301230391Skarels return(0); 301330391Skarels } 301430391Skarels 301530391Skarels if (key < LK_LOWEST) 301630391Skarels return(0); 301730391Skarels 301830391Skarels /*--------------------------------- 301930391Skarels * See if its a state change key */ 302030391Skarels 302130391Skarels switch (key) { 302230391Skarels 302330391Skarels case LOCK: 302430391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 302530391Skarels if (q_keyboard.lock) 302630391Skarels led_control(qd, LK_LED_ENABLE, LK_LED_LOCK); 302730391Skarels else 302830391Skarels led_control(qd, LK_LED_DISABLE, LK_LED_LOCK); 302930391Skarels return; 303030391Skarels 303130391Skarels case SHIFT: 303230391Skarels q_keyboard.shift ^= 0xFFFF; 303330391Skarels return; 303430391Skarels 303530391Skarels case CNTRL: 303630391Skarels q_keyboard.cntrl ^= 0xFFFF; 303730391Skarels return; 303830391Skarels 303930391Skarels case ALLUP: 304030391Skarels q_keyboard.cntrl = 0; 304130391Skarels q_keyboard.shift = 0; 304230391Skarels return; 304330391Skarels 304430391Skarels case REPEAT: 304530391Skarels chr = q_keyboard.last; 304630391Skarels break; 304730391Skarels 304830391Skarels /*------------------------------------------------------- 304930391Skarels * Test for cntrl characters. If set, see if the character 305030391Skarels * is elligible to become a control character. */ 305130391Skarels 305230391Skarels default: 305330391Skarels 305430391Skarels if (q_keyboard.cntrl) { 305530391Skarels chr = q_key[key]; 305630391Skarels if (chr >= ' ' && chr <= '~') 305730391Skarels chr &= 0x1F; 305830391Skarels } 305930391Skarels else if( q_keyboard.lock || q_keyboard.shift ) 306030391Skarels chr = q_shift_key[key]; 306130391Skarels else 306230391Skarels chr = q_key[key]; 306330391Skarels break; 306430391Skarels } 306530391Skarels 306630391Skarels q_keyboard.last = chr; 306730391Skarels 306830391Skarels /*----------------------------------- 306930391Skarels * Check for special function keys */ 307030391Skarels 307130391Skarels if (chr & 0x80) { 307230391Skarels char *string; 307330391Skarels string = q_special[chr & 0x7F]; 307430391Skarels while(*string) 307530391Skarels (*linesw[tp->t_line].l_rint)(*string++, tp); 307630391Skarels } 307730391Skarels else { 307830391Skarels (*linesw[tp->t_line].l_rint)(chr, tp); 307930391Skarels } 308030391Skarels } 308130391Skarels } 308230391Skarels 308330391Skarels return(0); 308430391Skarels 308530391Skarels } /* qdiint */ 308630391Skarels 308730391Skarels /****************************************************************** 308830391Skarels * 308930391Skarels * THE SUBROUTINES START HERE: 309030391Skarels * 309130391Skarels ******************************************************************/ 309230391Skarels 309330391Skarels /***************************************************************** 309430391Skarels * 309530391Skarels * clear_qd_screen()... clear the QDSS screen 309630391Skarels * 309730391Skarels ****************************************************************** 309830391Skarels * 309930391Skarels * >>> NOTE <<< 310030391Skarels * 310130391Skarels * This code requires that certain adder initialization be valid. To 310230391Skarels * assure that this requirement is satisfied, this routine should be 310330391Skarels * called only after calling the "setup_dragon()" function. 310430391Skarels * 310530391Skarels * Clear the bitmap a piece at a time. Since the fast scroll clear 310630391Skarels * only clears the current displayed portion of the bitmap put a 310730391Skarels * temporary value in the y limit register so we can access whole 310830391Skarels * bitmap 310930391Skarels * 311030391Skarels ****************/ 311130391Skarels 311230391Skarels clear_qd_screen(unit) 311330391Skarels int unit; 311430391Skarels { 311530391Skarels register struct adder *adder; 311630391Skarels adder = (struct adder *) qdmap[unit].adder; 311730391Skarels 311830391Skarels adder->x_limit = 1024; 311930391Skarels adder->y_limit = 2048 - CHAR_HEIGHT; 312030391Skarels adder->y_offset_pending = 0; 312130391Skarels 312230391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 312330391Skarels wait_status(adder, VSYNC); 312430391Skarels 312530391Skarels adder->y_scroll_constant = SCROLL_ERASE; 312630391Skarels 312730391Skarels wait_status(adder, VSYNC); 312830391Skarels wait_status(adder, VSYNC); 312930391Skarels 313030391Skarels adder->y_offset_pending = 864; 313130391Skarels 313230391Skarels wait_status(adder, VSYNC); 313330391Skarels wait_status(adder, VSYNC); 313430391Skarels 313530391Skarels adder->y_scroll_constant = SCROLL_ERASE; 313630391Skarels 313730391Skarels wait_status(adder, VSYNC); 313830391Skarels wait_status(adder, VSYNC); 313930391Skarels 314030391Skarels adder->y_offset_pending = 1728; 314130391Skarels 314230391Skarels wait_status(adder, VSYNC); 314330391Skarels wait_status(adder, VSYNC); 314430391Skarels 314530391Skarels adder->y_scroll_constant = SCROLL_ERASE; 314630391Skarels 314730391Skarels wait_status(adder, VSYNC); 314830391Skarels wait_status(adder, VSYNC); 314930391Skarels 315030391Skarels adder->y_offset_pending = 0; /* back to normal */ 315130391Skarels 315230391Skarels wait_status(adder, VSYNC); 315330391Skarels wait_status(adder, VSYNC); 315430391Skarels 315530391Skarels adder->x_limit = MAX_SCREEN_X; 315630391Skarels adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; 315730391Skarels 315830391Skarels } /* clear_qd_screen */ 315930391Skarels 316030391Skarels /********************************************************************** 316130391Skarels * 316230391Skarels * qdputc()... route kernel console output to display destination 316330391Skarels * 316430391Skarels *********************************************************************** 316530391Skarels * 316630391Skarels * calling convention: 316730391Skarels * 316830391Skarels * qdputc(chr); 316930391Skarels * 317030391Skarels * where: char chr; ;character for output 317130391Skarels * 317230391Skarels ****************/ 317330391Skarels 317430391Skarels qdputc(chr) 317530391Skarels register char chr; 317630391Skarels { 317730391Skarels 3178*32012Smarc /* if system is now physical, forget it (ie: crash DUMP) */ 317930391Skarels if ( (mfpr(MAPEN) & 1) == 0 ) 318030391Skarels return; 318130391Skarels 3182*32012Smarc blitc(0, chr & 0xff); 3183*32012Smarc if ((chr & 0177) == '\n') 3184*32012Smarc blitc(0, '\r'); 318530391Skarels 318630391Skarels 318730391Skarels } /* qdputc */ 318830391Skarels 318930391Skarels /******************************************************************* 319030391Skarels * 319130391Skarels * qdgetc()... get a character from the LK201 319230391Skarels * 319330391Skarels ******************************************************************* 319430391Skarels * 319530391Skarels * calling convention: 319630391Skarels * 319730391Skarels * qdgetc(); 319830391Skarels * 319930391Skarels * returns: the character read. 320030391Skarels * 320130391Skarels ****************/ 320230391Skarels 320330391Skarels qdgetc() 320430391Skarels { 320530391Skarels register short key; 320630391Skarels register char chr; 320730391Skarels register struct duart *duart; 320830391Skarels 320930391Skarels u_int status; 321030391Skarels 321130391Skarels duart = (struct duart *) qdmap[0].duart; 321230391Skarels 321330391Skarels /*-------------------------------------- 321430391Skarels * Get a character from the keyboard. */ 321530391Skarels 321630391Skarels LOOP: 321730391Skarels while (!((status = duart->statusA) & RCV_RDY)) 321830391Skarels ; 321930391Skarels 322030391Skarels key = duart->dataA; 322130391Skarels key &= 0xFF; 322230391Skarels 322330391Skarels /*-------------------------------------- 322430391Skarels * Check for various keyboard errors */ 322530391Skarels 322630391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 322730391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 322830391Skarels printf("Keyboard error, code = %x\n", key); 322930391Skarels return(0); 323030391Skarels } 323130391Skarels 323230391Skarels if (key < LK_LOWEST) 323330391Skarels return(0); 323430391Skarels 323530391Skarels /*--------------------------------- 323630391Skarels * See if its a state change key */ 323730391Skarels 323830391Skarels switch (key) { 323930391Skarels 324030391Skarels case LOCK: 324130391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 324230391Skarels if (q_keyboard.lock) 324330391Skarels led_control(LK_LED_ENABLE, LK_LED_LOCK); 324430391Skarels else 324530391Skarels led_control(LK_LED_DISABLE, LK_LED_LOCK); 324630391Skarels goto LOOP; 324730391Skarels 324830391Skarels case SHIFT: 324930391Skarels q_keyboard.shift ^= 0xFFFF; 325030391Skarels goto LOOP; 325130391Skarels 325230391Skarels case CNTRL: 325330391Skarels q_keyboard.cntrl ^= 0xFFFF; 325430391Skarels goto LOOP; 325530391Skarels 325630391Skarels case ALLUP: 325730391Skarels q_keyboard.cntrl = 0; 325830391Skarels q_keyboard.shift = 0; 325930391Skarels goto LOOP; 326030391Skarels 326130391Skarels case REPEAT: 326230391Skarels chr = q_keyboard.last; 326330391Skarels break; 326430391Skarels 326530391Skarels /*------------------------------------------------------- 326630391Skarels * Test for cntrl characters. If set, see if the character 326730391Skarels * is elligible to become a control character. */ 326830391Skarels 326930391Skarels default: 327030391Skarels 327130391Skarels if (q_keyboard.cntrl) { 327230391Skarels chr = q_key[key]; 327330391Skarels if (chr >= ' ' && chr <= '~') 327430391Skarels chr &= 0x1F; 327530391Skarels } 327630391Skarels else if ( q_keyboard.lock || q_keyboard.shift ) 327730391Skarels chr = q_shift_key[key]; 327830391Skarels else 327930391Skarels chr = q_key[key]; 328030391Skarels break; 328130391Skarels } 328230391Skarels 328330391Skarels if (chr < ' ' && chr > '~') /* if input is non-displayable */ 328430391Skarels return(0); /* ..then pitch it! */ 328530391Skarels 328630391Skarels q_keyboard.last = chr; 328730391Skarels 328830391Skarels /*----------------------------------- 328930391Skarels * Check for special function keys */ 329030391Skarels 329130391Skarels if (chr & 0x80) /* pitch the function keys */ 329230391Skarels return(0); 329330391Skarels else 329430391Skarels return(chr); 329530391Skarels 329630391Skarels } /* qdgetc */ 329730391Skarels 329830391Skarels /********************************************************************** 329930391Skarels * 330030391Skarels * ldcursor()... load the mouse cursor's template RAM bitmap 330130391Skarels * 330230391Skarels ********************************************************************* 330330391Skarels * 330430391Skarels * calling convention: 330530391Skarels * 330630391Skarels * ldcursor(unit, bitmap); 330730391Skarels * u_int unit; 330830391Skarels * short *bitmap; 330930391Skarels * 331030391Skarels ****************/ 331130391Skarels 331230391Skarels ldcursor(unit, bitmap) 331330391Skarels u_int unit; 331430391Skarels short *bitmap; 331530391Skarels { 331630391Skarels register struct dga *dga; 331730391Skarels register short *temp; 331830391Skarels register int i; 331930391Skarels 332030391Skarels int cursor; 332130391Skarels 332230391Skarels dga = (struct dga *) qdmap[unit].dga; 332330391Skarels temp = (short *) qdmap[unit].template; 332430391Skarels 332530391Skarels if (dga->csr & CURS_ENB) { /* if the cursor is enabled.. */ 332630391Skarels cursor = -1; /* ..note that.. */ 332730391Skarels dga->csr &= ~CURS_ENB; /* ..and shut it off */ 332830391Skarels } 332930391Skarels else { 333030391Skarels cursor = 0; 333130391Skarels } 333230391Skarels 333330391Skarels dga->csr &= ~CURS_ENB; /* shut off the cursor */ 333430391Skarels 333530391Skarels temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ 333630391Skarels /* ..of the 8k WORD template space */ 333730391Skarels for (i = 0; i < 32; ++i) 333830391Skarels *temp++ = *bitmap++; 333930391Skarels 334030391Skarels if (cursor) { /* if cursor was enabled.. */ 334130391Skarels dga->csr |= CURS_ENB; /* ..turn it back on */ 334230391Skarels } 334330391Skarels 334430391Skarels return(0); 334530391Skarels 334630391Skarels } /* ldcursor */ 334730391Skarels 334830391Skarels /********************************************************************** 334930391Skarels * 335030391Skarels * ldfont()... put the console font in the QDSS off-screen memory 335130391Skarels * 335230391Skarels *********************************************************************** 335330391Skarels * 335430391Skarels * calling convention: 335530391Skarels * 335630391Skarels * ldfont(unit); 335730391Skarels * u_int unit; ;QDSS unit number 335830391Skarels * 335930391Skarels ****************/ 336030391Skarels 336130391Skarels ldfont(unit) 336230391Skarels u_int unit; 336330391Skarels { 336430391Skarels register struct adder *adder; 336530391Skarels 336630391Skarels int i; /* scratch variables */ 336730391Skarels int j; 336830391Skarels int k; 336930391Skarels short packed; 337030391Skarels 337130391Skarels adder = (struct adder *) qdmap[unit].adder; 337230391Skarels 337330391Skarels /*------------------------------------------ 337430391Skarels * setup VIPER operand control registers */ 337530391Skarels 337630391Skarels write_ID(adder, MASK_1, 0xFFFF); 337730391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 337830391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 337930391Skarels 338030391Skarels write_ID(adder, SRC1_OCR_B, 338130391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 338230391Skarels write_ID(adder, SRC2_OCR_B, 338330391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 338430391Skarels write_ID(adder, DST_OCR_B, 338530391Skarels EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 338630391Skarels 338730391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 338830391Skarels 338930391Skarels /*-------------------------- 339030391Skarels * load destination data */ 339130391Skarels 339230391Skarels wait_status(adder, RASTEROP_COMPLETE); 339330391Skarels 339430391Skarels adder->destination_x = FONT_X; 339530391Skarels adder->destination_y = FONT_Y; 339630391Skarels adder->fast_dest_dx = FONT_WIDTH; 339730391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 339830391Skarels 339930391Skarels /*--------------------------------------- 340030391Skarels * setup for processor to bitmap xfer */ 340130391Skarels 340230391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 340330391Skarels adder->cmd = PBT | OCRB | 2 | DTE | 2; 340430391Skarels 340530391Skarels /*----------------------------------------------- 340630391Skarels * iteratively do the processor to bitmap xfer */ 340730391Skarels 340830391Skarels for (i = 0; i < ROWS; ++i) { 340930391Skarels 341030391Skarels /* PTOB a scan line */ 341130391Skarels 341230391Skarels for (j = 0, k = i; j < 48; ++j) { 341330391Skarels 341430391Skarels /* PTOB one scan of a char cell */ 341530391Skarels 341630391Skarels packed = q_font[k]; 341730391Skarels k += ROWS; 341830391Skarels packed |= ((short)q_font[k] << 8); 341930391Skarels k += ROWS; 342030391Skarels 342130391Skarels wait_status(adder, TX_READY); 342230391Skarels adder->id_data = packed; 342330391Skarels } 342430391Skarels } 342530391Skarels 342630391Skarels } /* ldfont */ 342730391Skarels 342830391Skarels /********************************************************************* 342930391Skarels * 343030391Skarels * led_control()... twiddle LK-201 LED's 343130391Skarels * 343230391Skarels ********************************************************************** 343330391Skarels * 343430391Skarels * led_control(unit, cmd, led_mask); 343530391Skarels * u_int unit; QDSS number 343630391Skarels * int cmd; LED enable/disable command 343730391Skarels * int led_mask; which LED(s) to twiddle 343830391Skarels * 343930391Skarels *************/ 344030391Skarels 344130391Skarels led_control(unit, cmd, led_mask) 344230391Skarels u_int unit; 344330391Skarels int cmd; 344430391Skarels int led_mask; 344530391Skarels { 344630391Skarels register int i; 344730391Skarels register int status; 344830391Skarels register struct duart *duart; 344930391Skarels 345030391Skarels duart = (struct duart *) qdmap[unit].duart; 345130391Skarels 345230391Skarels for (i = 1000; i > 0; --i) { 345330391Skarels if ((status = duart->statusA) & XMT_RDY) { 345430391Skarels duart->dataA = cmd; 345530391Skarels break; 345630391Skarels } 345730391Skarels } 345830391Skarels 345930391Skarels for (i = 1000; i > 0; --i) { 346030391Skarels if ((status = duart->statusA) & XMT_RDY) { 346130391Skarels duart->dataA = led_mask; 346230391Skarels break; 346330391Skarels } 346430391Skarels } 346530391Skarels 346630391Skarels if (i == 0) 346730391Skarels return(BAD); 346830391Skarels 346930391Skarels return(GOOD); 347030391Skarels 347130391Skarels } /* led_control */ 347230391Skarels 347330391Skarels /******************************************************************* 347430391Skarels * 347530391Skarels * scroll_up()... move the screen up one character height 347630391Skarels * 347730391Skarels ******************************************************************** 347830391Skarels * 347930391Skarels * calling convention: 348030391Skarels * 348130391Skarels * scroll_up(adder); 348230391Skarels * struct adder *adder; ;address of adder 348330391Skarels * 348430391Skarels ********/ 348530391Skarels 348630391Skarels scroll_up(adder) 348730391Skarels register struct adder *adder; 348830391Skarels { 348930391Skarels 349030391Skarels /*------------------------------------------ 349130391Skarels * setup VIPER operand control registers */ 349230391Skarels 349330391Skarels wait_status(adder, ADDRESS_COMPLETE); 349430391Skarels 349530391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 349630391Skarels 349730391Skarels write_ID(adder, MASK_1, 0xFFFF); 349830391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 349930391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 350030391Skarels 350130391Skarels write_ID(adder, SRC1_OCR_B, 350230391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 350330391Skarels write_ID(adder, DST_OCR_B, 350430391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 350530391Skarels 350630391Skarels /*---------------------------------------- 350730391Skarels * load DESTINATION origin and vectors */ 350830391Skarels 350930391Skarels adder->fast_dest_dy = 0; 351030391Skarels adder->slow_dest_dx = 0; 351130391Skarels adder->error_1 = 0; 351230391Skarels adder->error_2 = 0; 351330391Skarels 351430391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 351530391Skarels 351630391Skarels adder->destination_x = 0; 351730391Skarels adder->fast_dest_dx = 1024; 351830391Skarels 351930391Skarels adder->destination_y = 0; 352030391Skarels adder->slow_dest_dy = 864 - CHAR_HEIGHT; 352130391Skarels 352230391Skarels /*----------------------------------- 352330391Skarels * load SOURCE origin and vectors */ 352430391Skarels 352530391Skarels adder->source_1_x = 0; 352630391Skarels adder->source_1_dx = 1024; 352730391Skarels 352830391Skarels adder->source_1_y = 0 + CHAR_HEIGHT; 352930391Skarels adder->source_1_dy = 864 - CHAR_HEIGHT; 353030391Skarels 353130391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 353230391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 353330391Skarels 353430391Skarels /*-------------------------------------------- 353530391Skarels * do a rectangle clear of last screen line */ 353630391Skarels 353730391Skarels write_ID(adder, MASK_1, 0xffff); 353830391Skarels write_ID(adder, SOURCE, 0xffff); 353930391Skarels write_ID(adder,DST_OCR_B, 354030391Skarels (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); 354130391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); 354230391Skarels adder->error_1 = 0; 354330391Skarels adder->error_2 = 0; 354430391Skarels adder->slow_dest_dx = 0; /* set up the width of */ 354530391Skarels adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ 354630391Skarels 354730391Skarels adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; 354830391Skarels wait_status(adder, RASTEROP_COMPLETE); 354930391Skarels adder->destination_x = 0; 355030391Skarels adder->destination_y = 864 - CHAR_HEIGHT; 355130391Skarels 355230391Skarels adder->fast_dest_dx = 1024; /* set up the height */ 355330391Skarels adder->fast_dest_dy = 0; /* of rectangle */ 355430391Skarels 355530391Skarels write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); 355630391Skarels adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; 355730391Skarels 355830391Skarels } /* scroll_up */ 355930391Skarels 356030391Skarels /******************************************************************** 356130391Skarels * 356230391Skarels * init_shared()... init shared memory pointers and structures 356330391Skarels * 356430391Skarels ********************************************************************* 356530391Skarels * 356630391Skarels * calling convention: 356730391Skarels * 356830391Skarels * init_shared(unit); 356930391Skarels * u_int unit; 357030391Skarels * 357130391Skarels ****************/ 357230391Skarels 357330391Skarels init_shared(unit) 357430391Skarels register u_int unit; 357530391Skarels { 357630391Skarels register struct dga *dga; 357730391Skarels 357830391Skarels dga = (struct dga *) qdmap[unit].dga; 357930391Skarels 358030391Skarels /*-------------------------------------------------- 358130391Skarels * initialize the event queue pointers and header */ 358230391Skarels 358330391Skarels eq_header[unit] = (struct qdinput *) 358430391Skarels ((((int)event_shared & ~(0x01FF)) + 512) 358530391Skarels + (EVENT_BUFSIZE * unit)); 358630391Skarels 358730391Skarels eq_header[unit]->curs_pos.x = 0; 358830391Skarels eq_header[unit]->curs_pos.y = 0; 358930391Skarels 359030391Skarels dga->x_cursor = TRANX(eq_header[unit]->curs_pos.x); 359130391Skarels dga->y_cursor = TRANY(eq_header[unit]->curs_pos.y); 359230391Skarels 359330391Skarels eq_header[unit]->curs_box.left = 0; 359430391Skarels eq_header[unit]->curs_box.right = 0; 359530391Skarels eq_header[unit]->curs_box.top = 0; 359630391Skarels eq_header[unit]->curs_box.bottom = 0; 359730391Skarels 359830391Skarels /*--------------------------------------------------------- 359930391Skarels * assign a pointer to the DMA I/O buffer for this QDSS. */ 360030391Skarels 360130391Skarels DMAheader[unit] = (struct DMAreq_header *) 360230391Skarels (((int)(&DMA_shared[0] + 512) & ~0x1FF) 360330391Skarels + (DMAbuf_size * unit)); 360430391Skarels 360530391Skarels DMAheader[unit]->DMAreq = (struct DMAreq *) ((int)DMAheader[unit] 360630391Skarels + sizeof(struct DMAreq_header)); 360730391Skarels 360830391Skarels DMAheader[unit]->QBAreg = 0; 360930391Skarels DMAheader[unit]->status = 0; 361030391Skarels DMAheader[unit]->shared_size = DMAbuf_size; 361130391Skarels DMAheader[unit]->used = 0; 361230391Skarels DMAheader[unit]->size = 10; /* default = 10 requests */ 361330391Skarels DMAheader[unit]->oldest = 0; 361430391Skarels DMAheader[unit]->newest = 0; 361530391Skarels 361630391Skarels /*----------------------------------------------------------- 361730391Skarels * assign a pointer to the scroll structure for this QDSS. */ 361830391Skarels 361930391Skarels scroll[unit] = (struct scroll *) 362030391Skarels (((int)(&scroll_shared[0] + 512) & ~0x1FF) 362130391Skarels + (sizeof(struct scroll) * unit)); 362230391Skarels 362330391Skarels scroll[unit]->status = 0; 362430391Skarels scroll[unit]->viper_constant = 0; 362530391Skarels scroll[unit]->y_scroll_constant = 0; 362630391Skarels scroll[unit]->y_offset = 0; 362730391Skarels scroll[unit]->x_index_pending = 0; 362830391Skarels scroll[unit]->y_index_pending = 0; 362930391Skarels 363030391Skarels /*---------------------------------------------------------------- 363130391Skarels * assign a pointer to the color map write buffer for this QDSS */ 363230391Skarels 363330391Skarels color_buf[unit] = (struct color_buf *) 363430391Skarels (((int)(&color_shared[0] + 512) & ~0x1FF) 363530391Skarels + (COLOR_BUFSIZ * unit)); 363630391Skarels 363730391Skarels color_buf[unit]->status = 0; 363830391Skarels color_buf[unit]->count = 0; 363930391Skarels 364030391Skarels } /* init_shared */ 364130391Skarels 364230391Skarels /********************************************************************* 364330391Skarels * 364430391Skarels * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map 364530391Skarels * 364630391Skarels ********************************************************************** 364730391Skarels * 364830391Skarels * calling convention: 364930391Skarels * 365030391Skarels * setup_dragon(); 365130391Skarels * 365230391Skarels * return: NONE 365330391Skarels * 365430391Skarels ************************/ 365530391Skarels 365630391Skarels setup_dragon(unit) 365730391Skarels u_int unit; 365830391Skarels { 365930391Skarels 366030391Skarels register struct adder *adder; 366130391Skarels register struct dga *dga; 366230391Skarels short *memcsr; 366330391Skarels 366430391Skarels int i; /* general purpose variables */ 366530391Skarels int status; 366630391Skarels 366730391Skarels short top; /* clipping/scrolling boundaries */ 366830391Skarels short bottom; 366930391Skarels short right; 367030391Skarels short left; 367130391Skarels 367230391Skarels short *red; /* color map pointers */ 367330391Skarels short *green; 367430391Skarels short *blue; 367530391Skarels 367630391Skarels /*------------------ 367730391Skarels * init for setup */ 367830391Skarels 367930391Skarels adder = (struct adder *) qdmap[unit].adder; 368030391Skarels dga = (struct dga *) qdmap[unit].dga; 368130391Skarels memcsr = (short *) qdmap[unit].memcsr; 368230391Skarels 368330391Skarels dga->csr &= ~(DMA_IE | 0x700); /* halt DMA and kill the intrpts */ 368430391Skarels *memcsr = SYNC_ON; /* blank screen and turn off LED's */ 368530391Skarels adder->command = CANCEL; 368630391Skarels 368730391Skarels /*---------------------- 368830391Skarels * set monitor timing */ 368930391Skarels 369030391Skarels adder->x_scan_count_0 = 0x2800; 369130391Skarels adder->x_scan_count_1 = 0x1020; 369230391Skarels adder->x_scan_count_2 = 0x003A; 369330391Skarels adder->x_scan_count_3 = 0x38F0; 369430391Skarels adder->x_scan_count_4 = 0x6128; 369530391Skarels adder->x_scan_count_5 = 0x093A; 369630391Skarels adder->x_scan_count_6 = 0x313C; 369730391Skarels adder->sync_phase_adj = 0x0100; 369830391Skarels adder->x_scan_conf = 0x00C8; 369930391Skarels 370030391Skarels /*--------------------------------------------------------- 370130391Skarels * got a bug in secound pass ADDER! lets take care of it */ 370230391Skarels 370330391Skarels /* normally, just use the code in the following bug fix code, but to 370430391Skarels * make repeated demos look pretty, load the registers as if there was 370530391Skarels * no bug and then test to see if we are getting sync */ 370630391Skarels 370730391Skarels adder->y_scan_count_0 = 0x135F; 370830391Skarels adder->y_scan_count_1 = 0x3363; 370930391Skarels adder->y_scan_count_2 = 0x2366; 371030391Skarels adder->y_scan_count_3 = 0x0388; 371130391Skarels 371230391Skarels /* if no sync, do the bug fix code */ 371330391Skarels 371430391Skarels if (wait_status(adder, VSYNC) == BAD) { 371530391Skarels 371630391Skarels /* first load all Y scan registers with very short frame and 371730391Skarels * wait for scroll service. This guarantees at least one SYNC 371830391Skarels * to fix the pass 2 Adder initialization bug (synchronizes 371930391Skarels * XCINCH with DMSEEDH) */ 372030391Skarels 372130391Skarels adder->y_scan_count_0 = 0x01; 372230391Skarels adder->y_scan_count_1 = 0x01; 372330391Skarels adder->y_scan_count_2 = 0x01; 372430391Skarels adder->y_scan_count_3 = 0x01; 372530391Skarels 372630391Skarels wait_status(adder, VSYNC); /* delay at least 1 full frame time */ 372730391Skarels wait_status(adder, VSYNC); 372830391Skarels 372930391Skarels /* now load the REAL sync values (in reverse order just to 373030391Skarels * be safe. */ 373130391Skarels 373230391Skarels adder->y_scan_count_3 = 0x0388; 373330391Skarels adder->y_scan_count_2 = 0x2366; 373430391Skarels adder->y_scan_count_1 = 0x3363; 373530391Skarels adder->y_scan_count_0 = 0x135F; 373630391Skarels } 373730391Skarels 373830391Skarels *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ 373930391Skarels 374030391Skarels /*---------------------------- 374130391Skarels * zero the index registers */ 374230391Skarels 374330391Skarels adder->x_index_pending = 0; 374430391Skarels adder->y_index_pending = 0; 374530391Skarels adder->x_index_new = 0; 374630391Skarels adder->y_index_new = 0; 374730391Skarels adder->x_index_old = 0; 374830391Skarels adder->y_index_old = 0; 374930391Skarels 375030391Skarels adder->pause = 0; 375130391Skarels 375230391Skarels /*---------------------------------------- 375330391Skarels * set rasterop mode to normal pen down */ 375430391Skarels 375530391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 375630391Skarels 375730391Skarels /*-------------------------------------------------- 375830391Skarels * set the rasterop registers to a default values */ 375930391Skarels 376030391Skarels adder->source_1_dx = 1; 376130391Skarels adder->source_1_dy = 1; 376230391Skarels adder->source_1_x = 0; 376330391Skarels adder->source_1_y = 0; 376430391Skarels adder->destination_x = 0; 376530391Skarels adder->destination_y = 0; 376630391Skarels adder->fast_dest_dx = 1; 376730391Skarels adder->fast_dest_dy = 0; 376830391Skarels adder->slow_dest_dx = 0; 376930391Skarels adder->slow_dest_dy = 1; 377030391Skarels adder->error_1 = 0; 377130391Skarels adder->error_2 = 0; 377230391Skarels 377330391Skarels /*------------------------ 377430391Skarels * scale factor = unity */ 377530391Skarels 377630391Skarels adder->fast_scale = UNITY; 377730391Skarels adder->slow_scale = UNITY; 377830391Skarels 377930391Skarels /*------------------------------- 378030391Skarels * set the source 2 parameters */ 378130391Skarels 378230391Skarels adder->source_2_x = 0; 378330391Skarels adder->source_2_y = 0; 378430391Skarels adder->source_2_size = 0x0022; 378530391Skarels 378630391Skarels /*----------------------------------------------- 378730391Skarels * initialize plane addresses for eight vipers */ 378830391Skarels 378930391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 379030391Skarels write_ID(adder, PLANE_ADDRESS, 0x0000); 379130391Skarels 379230391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0002); 379330391Skarels write_ID(adder, PLANE_ADDRESS, 0x0001); 379430391Skarels 379530391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0004); 379630391Skarels write_ID(adder, PLANE_ADDRESS, 0x0002); 379730391Skarels 379830391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0008); 379930391Skarels write_ID(adder, PLANE_ADDRESS, 0x0003); 380030391Skarels 380130391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0010); 380230391Skarels write_ID(adder, PLANE_ADDRESS, 0x0004); 380330391Skarels 380430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0020); 380530391Skarels write_ID(adder, PLANE_ADDRESS, 0x0005); 380630391Skarels 380730391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0040); 380830391Skarels write_ID(adder, PLANE_ADDRESS, 0x0006); 380930391Skarels 381030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0080); 381130391Skarels write_ID(adder, PLANE_ADDRESS, 0x0007); 381230391Skarels 381330391Skarels /* initialize the external registers. */ 381430391Skarels 381530391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); 381630391Skarels write_ID(adder, CS_SCROLL_MASK, 0x00FF); 381730391Skarels 381830391Skarels /* initialize resolution mode */ 381930391Skarels 382030391Skarels write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ 382130391Skarels write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ 382230391Skarels 382330391Skarels /* initialize viper registers */ 382430391Skarels 382530391Skarels write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); 382630391Skarels write_ID(adder, SCROLL_FILL, 0x0000); 382730391Skarels 382830391Skarels /*---------------------------------------------------- 382930391Skarels * set clipping and scrolling limits to full screen */ 383030391Skarels 383130391Skarels for ( i = 1000, adder->status = 0 383230391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 383330391Skarels ; --i); 383430391Skarels 383530391Skarels if (i == 0) 383630391Skarels mprintf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 383730391Skarels 383830391Skarels top = 0; 383930391Skarels bottom = 2048; 384030391Skarels left = 0; 384130391Skarels right = 1024; 384230391Skarels 384330391Skarels adder->x_clip_min = left; 384430391Skarels adder->x_clip_max = right; 384530391Skarels adder->y_clip_min = top; 384630391Skarels adder->y_clip_max = bottom; 384730391Skarels 384830391Skarels adder->scroll_x_min = left; 384930391Skarels adder->scroll_x_max = right; 385030391Skarels adder->scroll_y_min = top; 385130391Skarels adder->scroll_y_max = bottom; 385230391Skarels 385330391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 385430391Skarels wait_status(adder, VSYNC); 385530391Skarels 385630391Skarels adder->x_index_pending = left; 385730391Skarels adder->y_index_pending = top; 385830391Skarels adder->x_index_new = left; 385930391Skarels adder->y_index_new = top; 386030391Skarels adder->x_index_old = left; 386130391Skarels adder->y_index_old = top; 386230391Skarels 386330391Skarels for ( i = 1000, adder->status = 0 386430391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 386530391Skarels ; --i); 386630391Skarels 386730391Skarels if (i == 0) 386830391Skarels mprintf("\nqd%d: setup_dragon: timeout on ADDRESS_COMPLETE",unit); 386930391Skarels 387030391Skarels write_ID(adder, LEFT_SCROLL_MASK, 0x0000); 387130391Skarels write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); 387230391Skarels 387330391Skarels /*------------------------------------------------------------ 387430391Skarels * set source and the mask register to all ones (ie: white) */ 387530391Skarels 387630391Skarels write_ID(adder, SOURCE, 0xFFFF); 387730391Skarels write_ID(adder, MASK_1, 0xFFFF); 387830391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 387930391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 388030391Skarels 388130391Skarels /*-------------------------------------------------------------- 388230391Skarels * initialize Operand Control Register banks for fill command */ 388330391Skarels 388430391Skarels write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); 388530391Skarels write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); 388630391Skarels write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 388730391Skarels 388830391Skarels write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); 388930391Skarels write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); 389030391Skarels write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 389130391Skarels 389230391Skarels /*------------------------------------------------------------------ 389330391Skarels * init Logic Unit Function registers, (these are just common values, 389430391Skarels * and may be changed as required). */ 389530391Skarels 389630391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 389730391Skarels write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); 389830391Skarels write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); 389930391Skarels write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); 390030391Skarels 390130391Skarels /*---------------------------------------- 390230391Skarels * load the color map for black & white */ 390330391Skarels 390430391Skarels for ( i = 0, adder->status = 0 390530391Skarels ; i < 10000 && !((status = adder->status) & VSYNC) 390630391Skarels ; ++i); 390730391Skarels 390830391Skarels if (i == 0) 390930391Skarels mprintf("\nqd%d: setup_dragon: timeout on VSYNC", unit); 391030391Skarels 391130391Skarels red = (short *) qdmap[unit].red; 391230391Skarels green = (short *) qdmap[unit].green; 391330391Skarels blue = (short *) qdmap[unit].blue; 391430391Skarels 391530391Skarels *red++ = 0x00; /* black */ 391630391Skarels *green++ = 0x00; 391730391Skarels *blue++ = 0x00; 391830391Skarels 391930391Skarels *red-- = 0xFF; /* white */ 392030391Skarels *green-- = 0xFF; 392130391Skarels *blue-- = 0xFF; 392230391Skarels 392330391Skarels /*---------------------------------- 392430391Skarels * set color map for mouse cursor */ 392530391Skarels 392630391Skarels red += 254; 392730391Skarels green += 254; 392830391Skarels blue += 254; 392930391Skarels 393030391Skarels *red++ = 0x00; /* black */ 393130391Skarels *green++ = 0x00; 393230391Skarels *blue++ = 0x00; 393330391Skarels 393430391Skarels *red = 0xFF; /* white */ 393530391Skarels *green = 0xFF; 393630391Skarels *blue = 0xFF; 393730391Skarels 393830391Skarels return(0); 393930391Skarels 394030391Skarels } /* setup_dragon */ 394130391Skarels 394230391Skarels /****************************************************************** 394330391Skarels * 394430391Skarels * setup_input()... init the DUART and set defaults in input 394530391Skarels * devices 394630391Skarels * 394730391Skarels ******************************************************************* 394830391Skarels * 394930391Skarels * calling convention: 395030391Skarels * 395130391Skarels * setup_input(unit); 395230391Skarels * 395330391Skarels * where: unit - is the QDSS unit number to be setup 395430391Skarels * 395530391Skarels *********/ 395630391Skarels 395730391Skarels setup_input(unit) 395830391Skarels u_int unit; 395930391Skarels { 396030391Skarels register struct duart *duart; /* DUART register structure pointer */ 396130391Skarels register int i; /* scratch variable */ 396230391Skarels register int bits; 396330391Skarels 396430391Skarels char id_byte; 396530391Skarels short status; 396630391Skarels 396730391Skarels /*--------------- 396830391Skarels * init stuff */ 396930391Skarels 397030391Skarels duart = (struct duart *) qdmap[unit].duart; 397130391Skarels duart->imask = 0; 397230391Skarels 397330391Skarels /*--------------------------------------------- 397430391Skarels * setup the DUART for kbd & pointing device */ 397530391Skarels 397630391Skarels duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ 397730391Skarels duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ 397830391Skarels /* no RTS control,char error mode */ 397930391Skarels duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ 398030391Skarels /* no RTS control,no echo or loop */ 398130391Skarels duart->cmdB = RESET_M; /* reset mode reg pntr for host */ 398230391Skarels duart->modeB = 0x07; /* 8 bits, odd parity, rcv IE.. */ 398330391Skarels /* ..no RTS cntrl, char error mode */ 398430391Skarels duart->modeB = 0x07; /* 1 stop bit,CTS does not IE XMT */ 398530391Skarels /* no RTS control,no echo or loop */ 398630391Skarels 398730391Skarels duart->auxctl = 0x00; /* baud rate set 1 */ 398830391Skarels 398930391Skarels duart->clkselA = 0x99; /* 4800 baud for kbd */ 399030391Skarels duart->clkselB = 0x99; /* 4800 baud for mouse */ 399130391Skarels 399230391Skarels /* reset everything for keyboard */ 399330391Skarels 399430391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 399530391Skarels duart->cmdA = bits; 399630391Skarels 399730391Skarels /* reset everything for host */ 399830391Skarels 399930391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 400030391Skarels duart->cmdB = bits; 400130391Skarels 400230391Skarels duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ 400330391Skarels duart->cmdB = EN_RCV | EN_XMT; /* enbl xmt & rcv for pointer device */ 400430391Skarels 400530391Skarels /*-------------------------------------------- 400630391Skarels * init keyboard defaults (DUART channel A) */ 400730391Skarels 400830391Skarels for (i = 500; i > 0; --i) { 400930391Skarels if ((status = duart->statusA) & XMT_RDY) { 401030391Skarels duart->dataA = LK_DEFAULTS; 401130391Skarels break; 401230391Skarels } 401330391Skarels } 401430391Skarels 401530391Skarels for (i = 100000; i > 0; --i) { 401630391Skarels if ((status = duart->statusA) & RCV_RDY) { 401730391Skarels break; 401830391Skarels } 401930391Skarels } 402030391Skarels 402130391Skarels status = duart->dataA; /* flush the ACK */ 402230391Skarels 402330391Skarels /*-------------------------------- 402430391Skarels * identify the pointing device */ 402530391Skarels 402630391Skarels for (i = 500; i > 0; --i) { 402730391Skarels if ((status = duart->statusB) & XMT_RDY) { 402830391Skarels duart->dataB = SELF_TEST; 402930391Skarels break; 403030391Skarels } 403130391Skarels } 403230391Skarels 403330391Skarels /*----------------------------------------- 403430391Skarels * wait for 1st byte of self test report */ 403530391Skarels 403630391Skarels for (i = 100000; i > 0; --i) { 403730391Skarels if ((status = duart->statusB) & RCV_RDY) { 403830391Skarels break; 403930391Skarels } 404030391Skarels } 404130391Skarels 404230391Skarels if (i == 0) { 404330391Skarels mprintf("\nqd[%d]: setup_input: timeout on 1st byte of self test",unit); 404430391Skarels goto OUT; 404530391Skarels } 404630391Skarels 404730391Skarels status = duart->dataB; 404830391Skarels 404930391Skarels /*----------------------------------------- 405030391Skarels * wait for ID byte of self test report */ 405130391Skarels 405230391Skarels for (i = 100000; i > 0; --i) { 405330391Skarels if ((status = duart->statusB) & RCV_RDY) { 405430391Skarels break; 405530391Skarels } 405630391Skarels } 405730391Skarels 405830391Skarels if (i == 0) { 405930391Skarels mprintf("\nqd[%d]: setup_input: timeout on 2nd byte of self test", unit); 406030391Skarels goto OUT; 406130391Skarels } 406230391Skarels 406330391Skarels id_byte = duart->dataB; 406430391Skarels 406530391Skarels /*------------------------------------ 406630391Skarels * wait for other bytes to come in */ 406730391Skarels 406830391Skarels for (i = 100000; i > 0; --i) { 406930391Skarels if ((status = duart->statusB) & RCV_RDY) { 407030391Skarels status = duart->dataB; 407130391Skarels break; 407230391Skarels } 407330391Skarels } 407430391Skarels 407530391Skarels if (i == 0) { 407630391Skarels mprintf("\nqd[%d]: setup_input: timeout on 3rd byte of self test", unit); 407730391Skarels goto OUT; 407830391Skarels } 407930391Skarels 408030391Skarels for (i = 100000; i > 0; --i) { 408130391Skarels if ((status = duart->statusB) & RCV_RDY) { 408230391Skarels status = duart->dataB; 408330391Skarels break; 408430391Skarels } 408530391Skarels } 408630391Skarels 408730391Skarels if (i == 0) { 408830391Skarels mprintf("\nqd[%d]: setup_input: timeout on 4th byte of self test\n", unit); 408930391Skarels goto OUT; 409030391Skarels } 409130391Skarels 409230391Skarels /*---------------------------------------------- 409330391Skarels * flag pointing device type and set defaults */ 409430391Skarels 409530391Skarels for (i=100000; i>0; --i); 409630391Skarels 409730391Skarels if ((id_byte & 0x0F) != TABLET_ID) { 409830391Skarels 409930391Skarels qdflags[unit].pntr_id = MOUSE_ID; 410030391Skarels 410130391Skarels for (i = 500; i > 0; --i) { 410230391Skarels if ((status = duart->statusB) & XMT_RDY) { 410330391Skarels duart->dataB = INC_STREAM_MODE; 410430391Skarels break; 410530391Skarels } 410630391Skarels } 410730391Skarels } else { 410830391Skarels 410930391Skarels qdflags[unit].pntr_id = TABLET_ID; 411030391Skarels 411130391Skarels for (i = 500; i > 0; --i) { 411230391Skarels if ((status = duart->statusB) & XMT_RDY) { 411330391Skarels duart->dataB = T_STREAM; 411430391Skarels break; 411530391Skarels } 411630391Skarels } 411730391Skarels } 411830391Skarels 411930391Skarels /*-------- 412030391Skarels * exit */ 412130391Skarels 412230391Skarels OUT: 412330391Skarels duart->imask = qdflags[unit].duart_imask; 412430391Skarels return(0); 412530391Skarels 412630391Skarels } /* setup_input */ 412730391Skarels 412830391Skarels /********************************************************************** 412930391Skarels * 413030391Skarels * wait_status()... delay for at least one display frame time 413130391Skarels * 413230391Skarels *********************************************************************** 413330391Skarels * 413430391Skarels * calling convention: 413530391Skarels * 413630391Skarels * wait_status(adder, mask); 413730391Skarels * struct *adder adder; 413830391Skarels * int mask; 413930391Skarels * 414030391Skarels * return: BAD means that we timed out without ever seeing the 414130391Skarels * vertical sync status bit 414230391Skarels * GOOD otherwise 414330391Skarels * 414430391Skarels **************/ 414530391Skarels 414630391Skarels wait_status(adder, mask) 414730391Skarels register struct adder *adder; 414830391Skarels register int mask; 414930391Skarels { 415030391Skarels register short status; 415130391Skarels int i; 415230391Skarels 415330391Skarels for ( i = 10000, adder->status = 0 415430391Skarels ; i > 0 && !((status = adder->status) & mask) 415530391Skarels ; --i); 415630391Skarels 415730391Skarels if (i == 0) { 415830391Skarels mprintf("\nwait_status: timeout polling for 0x%x in adder->status", mask); 415930391Skarels return(BAD); 416030391Skarels } 416130391Skarels 416230391Skarels return(GOOD); 416330391Skarels 416430391Skarels } /* wait_status */ 416530391Skarels 416630391Skarels /********************************************************************** 416730391Skarels * 416830391Skarels * write_ID()... write out onto the ID bus 416930391Skarels * 417030391Skarels *********************************************************************** 417130391Skarels * 417230391Skarels * calling convention: 417330391Skarels * 417430391Skarels * struct *adder adder; ;pntr to ADDER structure 417530391Skarels * short adrs; ;VIPER address 417630391Skarels * short data; ;data to be written 417730391Skarels * write_ID(adder); 417830391Skarels * 417930391Skarels * return: BAD means that we timed out waiting for status bits 418030391Skarels * VIPER-access-specific status bits 418130391Skarels * GOOD otherwise 418230391Skarels * 418330391Skarels **************/ 418430391Skarels 418530391Skarels write_ID(adder, adrs, data) 418630391Skarels register struct adder *adder; 418730391Skarels register short adrs; 418830391Skarels register short data; 418930391Skarels { 419030391Skarels int i; 419130391Skarels short status; 419230391Skarels 419330391Skarels for ( i = 100000, adder->status = 0 419430391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 419530391Skarels ; --i); 419630391Skarels 419730391Skarels if (i == 0) 419830391Skarels goto ERR; 419930391Skarels 420030391Skarels for ( i = 100000, adder->status = 0 420130391Skarels ; i > 0 && !((status = adder->status) & TX_READY) 420230391Skarels ; --i); 420330391Skarels 420430391Skarels if (i > 0) { 420530391Skarels adder->id_data = data; 420630391Skarels adder->command = ID_LOAD | adrs; 420730391Skarels return(GOOD); 420830391Skarels } 420930391Skarels 421030391Skarels ERR: 421130391Skarels mprintf("\nwrite_ID: timeout trying to write to VIPER"); 421230391Skarels return(BAD); 421330391Skarels 421430391Skarels } /* write_ID */ 4215