1*34511Smarc /* 2*34511Smarc * Copyright (c) 1982, 1986 Regents of the University of California. 3*34511Smarc * All rights reserved. The Berkeley software License Agreement 4*34511Smarc * specifies the terms and conditions for redistribution. 5*34511Smarc * 6*34511Smarc * @(#)qd.c 1.3 Berkeley 05/26/88 7*34511Smarc * 8*34511Smarc * derived from: "@(#)qd.c 1.40 ULTRIX 10/2/86"; 9*34511Smarc */ 1030391Skarels 1130391Skarels /************************************************************************ 12*34511Smarc * * 13*34511Smarc * Copyright (c) 1985, 1986 by * 1430391Skarels * Digital Equipment Corporation, Maynard, MA * 1530391Skarels * All rights reserved. * 1630391Skarels * * 1730391Skarels * This software is furnished under a license and may be used and * 1830391Skarels * copied only in accordance with the terms of such license and * 1930391Skarels * with the inclusion of the above copyright notice. This * 2030391Skarels * software or any other copies thereof may not be provided or * 2130391Skarels * otherwise made available to any other person. No title to and * 2230391Skarels * ownership of the software is hereby transferred. * 2330391Skarels * * 2430391Skarels * The information in this software is subject to change without * 2530391Skarels * notice and should not be construed as a commitment by Digital * 2630391Skarels * Equipment Corporation. * 2730391Skarels * * 2830391Skarels * Digital assumes no responsibility for the use or reliability * 2930391Skarels * of its software on equipment which is not supplied by Digital. * 3030391Skarels * * 3130391Skarels *************************************************************************/ 3230391Skarels /* 33*34511Smarc * qd.c - QDSS display driver 3430391Skarels */ 3530391Skarels 36*34511Smarc #include "qd.h" 37*34511Smarc #if NQD > 0 3830391Skarels 39*34511Smarc #include "../machine/pte.h" 40*34511Smarc #include "../machine/mtpr.h" 41*34511Smarc #include "../machine/cpu.h" 42*34511Smarc #include "param.h" 43*34511Smarc #include "conf.h" 44*34511Smarc #include "dir.h" 45*34511Smarc #include "user.h" 46*34511Smarc #include "qdioctl.h" 47*34511Smarc #include "tty.h" 48*34511Smarc #include "map.h" 49*34511Smarc #include "buf.h" 50*34511Smarc #include "vm.h" 51*34511Smarc #include "clist.h" 52*34511Smarc #include "file.h" 53*34511Smarc #include "uio.h" 54*34511Smarc #include "kernel.h" 55*34511Smarc #include "ubareg.h" 56*34511Smarc #include "ubavar.h" 57*34511Smarc #include "syslog.h" 58*34511Smarc #include "qduser.h" /* definitions shared with client */ 59*34511Smarc #include "qdreg.h" 6030391Skarels 6132012Smarc /* 6232012Smarc * QDSS driver status flags for tracking operational state 6332012Smarc */ 6432012Smarc 6532012Smarc struct qdflags { 6632012Smarc 6732012Smarc u_int inuse; /* which minor dev's are in use now */ 6832012Smarc u_int config; /* I/O page register content */ 6932012Smarc u_int mapped; /* user mapping status word */ 7032012Smarc u_int kernel_loop; /* if kernel console is redirected */ 7132012Smarc u_int user_dma; /* DMA from user space in progress */ 7232012Smarc u_short pntr_id; /* type code of pointing device */ 7332012Smarc u_short duart_imask; /* shadowing for duart intrpt mask reg */ 7432012Smarc u_short adder_ie; /* shadowing for adder intrpt enbl reg */ 7532012Smarc u_short curs_acc; /* cursor acceleration factor */ 7632012Smarc u_short curs_thr; /* cursor acceleration threshold level */ 7732012Smarc u_short tab_res; /* tablet resolution factor */ 7832012Smarc u_short selmask; /* mask for active qd select entries */ 7932012Smarc }; 8032012Smarc 81*34511Smarc /* #define POSIXTTY (4.4BSD) */ 82*34511Smarc 8332012Smarc /* bit definitions for "inuse" entry */ 8432012Smarc #define CONS_DEV 0x01 8532012Smarc #define ALTCONS_DEV 0x02 8632012Smarc #define GRAPHIC_DEV 0x04 8732012Smarc 8832012Smarc /* bit definitions for 'mapped' member of flag structure */ 8932012Smarc #define MAPDEV 0x01 /* hardware is mapped */ 9032012Smarc #define MAPDMA 0x02 /* DMA buffer mapped */ 9132012Smarc #define MAPEQ 0x04 /* event queue buffer mapped */ 9232012Smarc #define MAPSCR 0x08 /* scroll param area mapped */ 9332012Smarc #define MAPCOLOR 0x10 /* color map writing buffer mapped */ 9432012Smarc 9532012Smarc /* bit definitions for 'selmask' member of qdflag structure */ 9632012Smarc 9732012Smarc #define SEL_READ 0x01 /* read select is active */ 9832012Smarc #define SEL_WRITE 0x02 /* write select is active */ 9932012Smarc 10032012Smarc /* 10132012Smarc * constants used in shared memory operations 10232012Smarc */ 10332012Smarc 10432012Smarc #define EVENT_BUFSIZE 1024 /* # of bytes per device's event buffer */ 10532012Smarc #define MAXEVENTS ( (EVENT_BUFSIZE - sizeof(struct qdinput)) \ 10632012Smarc / sizeof(struct _vs_event) ) 10732012Smarc #define DMA_BUFSIZ (1024 * 3) 10832012Smarc #define COLOR_BUFSIZ ((sizeof(struct color_buf) + 512) & ~0x01FF) 10932012Smarc 11032012Smarc /* 11132012Smarc * reference to an array of "uba_device" structures built by the auto 11232012Smarc * configuration program. The uba_device structure decribes the device 11332012Smarc * sufficiently for the driver to talk to it. The auto configuration code 11432012Smarc * fills in the uba_device structures (located in ioconf.c) from user 11532012Smarc * maintained info. 11632012Smarc */ 11732012Smarc 11832012Smarc struct uba_device *qdinfo[NQD]; /* array of pntrs to each QDSS's */ 11932012Smarc /* uba structures */ 12032012Smarc struct tty qd_tty[NQD*4]; /* teletype structures for each.. */ 12132012Smarc /* ..possible minor device */ 12232012Smarc 12332012Smarc struct qd_softc qd_softc[NQD]; 12432012Smarc 12532012Smarc /* 126*34511Smarc * static storage used by multiple functions in this code 127*34511Smarc */ 12832012Smarc int Qbus_unmap[NQD]; /* Qbus mapper release code */ 12932012Smarc struct qdflags qdflags[NQD]; /* QDSS device status flags */ 13032012Smarc struct qdmap qdmap[NQD]; /* QDSS register map structure */ 13132012Smarc caddr_t qdbase[NQD]; /* base address of each QDSS unit */ 13232012Smarc struct buf qdbuf[NQD]; /* buf structs used by strategy */ 13332012Smarc char one_only[NQD]; /* lock for single process access */ 13432012Smarc 13532012Smarc /* 13632012Smarc * The array "event_shared[]" is made up of a number of event queue buffers 13732012Smarc * equal to the number of QDSS's configured into the running kernel (NQD). 13832012Smarc * Each event queue buffer begins with an event queue header (struct qdinput) 13932012Smarc * followed by a group of event queue entries (struct _vs_event). The array 14032012Smarc * "*eq_header[]" is an array of pointers to the start of each event queue 14132012Smarc * buffer in "event_shared[]". 14232012Smarc */ 14332012Smarc 14432012Smarc #define EQSIZE ((EVENT_BUFSIZE * NQD) + 512) 14532012Smarc 14632012Smarc char event_shared[EQSIZE]; /* reserve space for event bufs */ 14732012Smarc struct qdinput *eq_header[NQD]; /* event queue header pntrs */ 14832012Smarc 14932012Smarc /* 15032012Smarc * This allocation method reserves enough memory pages for NQD shared DMA I/O 15132012Smarc * buffers. Each buffer must consume an integral number of memory pages to 15232012Smarc * guarantee that a following buffer will begin on a page boundary. Also, 15332012Smarc * enough space is allocated so that the FIRST I/O buffer can start at the 15432012Smarc * 1st page boundary after "&DMA_shared". Page boundaries are used so that 15532012Smarc * memory protections can be turned on/off for individual buffers. 15632012Smarc */ 15732012Smarc 15832012Smarc #define IOBUFSIZE ((DMA_BUFSIZ * NQD) + 512) 15932012Smarc 16032012Smarc char DMA_shared[IOBUFSIZE]; /* reserve I/O buffer space */ 16132012Smarc struct DMAreq_header *DMAheader[NQD]; /* DMA buffer header pntrs */ 16232012Smarc 16332012Smarc /* 16432012Smarc * The driver assists a client in scroll operations by loading dragon 16532012Smarc * registers from an interrupt service routine. The loading is done using 16632012Smarc * parameters found in memory shrade between the driver and it's client. 16732012Smarc * The scroll parameter structures are ALL loacted in the same memory page 16832012Smarc * for reasons of memory economy. 16932012Smarc */ 17032012Smarc 17132012Smarc char scroll_shared[2 * 512]; /* reserve space for scroll structs */ 17232012Smarc struct scroll *scroll[NQD]; /* pointers to scroll structures */ 17332012Smarc 17432012Smarc /* 17532012Smarc * the driver is programmable to provide the user with color map write 17632012Smarc * services at VSYNC interrupt time. At interrupt time the driver loads 17732012Smarc * the color map with any user-requested load data found in shared memory 17832012Smarc */ 17932012Smarc 18032012Smarc #define COLOR_SHARED ((COLOR_BUFSIZ * NQD) + 512) 18132012Smarc 182*34511Smarc char color_shared[COLOR_SHARED]; /* color bufs */ 18332012Smarc struct color_buf *color_buf[NQD]; /* pointers to color bufs */ 18432012Smarc 18532012Smarc /* 18632012Smarc * mouse input event structures 18732012Smarc */ 18832012Smarc 18932012Smarc struct mouse_report last_rep[NQD]; 19032012Smarc struct mouse_report current_rep[NQD]; 19132012Smarc 19232012Smarc /* 19332012Smarc * input event "select" use 19432012Smarc */ 19532012Smarc 19632012Smarc struct proc *rsel[NQD]; /* process waiting for select */ 19732012Smarc 19832012Smarc /* 19932012Smarc * console cursor structure 20032012Smarc */ 20132012Smarc 20232012Smarc struct _vs_cursor cursor[NQD]; 20332012Smarc 20432012Smarc 20532012Smarc 20632012Smarc int nNQD = NQD; 20732012Smarc 20832012Smarc int DMAbuf_size = DMA_BUFSIZ; 20932012Smarc 21032012Smarc 21132012Smarc /* 21232012Smarc * macro to get system time. Used to time stamp event queue entries 21332012Smarc */ 21432012Smarc 21530391Skarels #define TOY ((time.tv_sec * 100) + (time.tv_usec / 10000)) 21630391Skarels 21732012Smarc /* 21830391Skarels * the "ioconf.c" program, built and used by auto config, externally refers 21932012Smarc * to definitions below. 22032012Smarc */ 22130391Skarels 22232012Smarc int qdprobe(); 22332012Smarc int qdattach(); 22432012Smarc int qddint(); /* DMA gate array intrpt service */ 22532012Smarc int qdaint(); /* Dragon ADDER intrpt service */ 22632012Smarc int qdiint(); 22730391Skarels 22832012Smarc u_short qdstd[] = { 0 }; 22930391Skarels 23032012Smarc struct uba_driver qddriver = { /* externally referenced: ioconf.c */ 23130391Skarels 23232012Smarc qdprobe, /* device probe entry */ 23332012Smarc 0, /* no slave device */ 23432012Smarc qdattach, /* device attach entry */ 23532012Smarc 0, /* no "fill csr/ba to start" */ 23632012Smarc qdstd, /* device addresses */ 23732012Smarc "qd", /* device name string */ 23832012Smarc qdinfo /* ptr to QDSS's uba_device struct */ 23932012Smarc }; 24030391Skarels 24132012Smarc extern char qvmem[][128*NBPG]; 24232012Smarc extern struct pte QVmap[][128]; 24332012Smarc 24432012Smarc /* 24532012Smarc * v_putc is used to redirect the console cnputc to the virtual console 24632012Smarc * vputc. consops is used to direct the console device to the qvss console. 24732012Smarc */ 24832012Smarc extern (*v_putc)(); 24932012Smarc extern struct cdevsw *consops; 25032012Smarc 25132012Smarc /* 25230391Skarels * general defines */ 25330391Skarels 254*34511Smarc #define QDPRIOR (PZERO-1) 25530391Skarels 25630391Skarels #define FALSE 0 25730391Skarels #define TRUE ~FALSE 25830391Skarels 25930391Skarels #define BAD -1 26030391Skarels #define GOOD 0 26130391Skarels 26232012Smarc /* 26332012Smarc * Macro to create a system virtual page number from system virtual adrs. 26432012Smarc */ 26530391Skarels 26632012Smarc #define VTOP(x) (((int)x & ~0xC0000000) >> PGSHIFT) 26730391Skarels 26832012Smarc /* 26932012Smarc * QDSS register address offsets from start of QDSS address space 27032012Smarc */ 27130391Skarels 27230391Skarels #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ 27330391Skarels 27430391Skarels #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ 27530391Skarels #define TMPSTART 0x8000 /* offset of template RAM from base adrs */ 27630391Skarels 27730391Skarels #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ 27830391Skarels #define REGSTART 0xC000 /* offset of reg pages from base adrs */ 27930391Skarels 28030391Skarels #define ADDER (REGSTART+0x000) 28130391Skarels #define DGA (REGSTART+0x200) 28230391Skarels #define DUART (REGSTART+0x400) 28330391Skarels #define MEMCSR (REGSTART+0x800) 28430391Skarels 28530391Skarels #define CLRSIZE (3 * 512) /* color map size */ 28630391Skarels #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ 28730391Skarels /* 0x0C00 really */ 28830391Skarels #define RED (CLRSTART+0x000) 28930391Skarels #define BLUE (CLRSTART+0x200) 29030391Skarels #define GREEN (CLRSTART+0x400) 29130391Skarels 29232012Smarc /* 29332012Smarc * Values used in mapping QDSS hardware into the Q memory space. 29432012Smarc */ 29530391Skarels 29630391Skarels #define CHUNK (64 * 1024) 29732012Smarc #define QMEMSIZE (1024 * 1024 * 4) 29830391Skarels 29932012Smarc /* 30030391Skarels * QDSS minor device numbers. The *real* minor device numbers are in 30130391Skarels * the bottom two bits of the major/minor device spec. Bits 2 and up are 30232012Smarc * used to specify the QDSS device number (ie: which one?) 30332012Smarc */ 30430391Skarels 30532012Smarc #define QDSSMAJOR 41 /* QDSS major device number */ 30630391Skarels 30730391Skarels #define CONS 0 30830391Skarels #define ALTCONS 1 30930391Skarels #define GRAPHIC 2 31030391Skarels 31132012Smarc /* 31232012Smarc * console cursor bitmap (block cursor type) 31332012Smarc */ 31430391Skarels 31530391Skarels short cons_cursor[32] = { /* white block cursor */ 31630391Skarels 31730391Skarels /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 31830391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 31930391Skarels /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 32030391Skarels 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF 32130391Skarels 32230391Skarels }; 32330391Skarels 32432012Smarc /* 32532012Smarc * constants used in font operations 32632012Smarc */ 32730391Skarels 32830391Skarels #define CHARS 95 /* # of chars in the font */ 32930391Skarels #define CHAR_HEIGHT 15 /* char height in pixels */ 33030391Skarels #define CHAR_WIDTH 8 /* char width in pixels*/ 33130391Skarels #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ 33230391Skarels #define ROWS CHAR_HEIGHT 33330391Skarels 33430391Skarels 33530391Skarels #define FONT_X 0 /* font's off screen adrs */ 33630391Skarels #define FONT_Y (2048 - CHAR_HEIGHT) 33730391Skarels /* 33830391Skarels #define FONT_Y 200 33930391Skarels */ 34030391Skarels 34132012Smarc extern char q_font[]; /* reference font object code */ 34230391Skarels 34332012Smarc extern char q_key[]; /* reference key xlation tables */ 34432012Smarc extern char q_shift_key[]; 34532012Smarc extern char *q_special[]; 34630391Skarels 34732012Smarc /* 34832012Smarc * definitions for cursor acceleration reporting 34932012Smarc */ 35030391Skarels 35130391Skarels #define ACC_OFF 0x01 /* acceleration is inactive */ 35230391Skarels 35332012Smarc int qdputc(); /* used to direct kernel console output * 35432012Smarc int qdstart(); /* used to direct /dev/console output * 35530391Skarels 35632012Smarc /* 35732012Smarc * LK-201 state storage for input console keyboard conversion to ASCII 35832012Smarc */ 35930391Skarels 36032012Smarc struct q_keyboard { 36132012Smarc int shift; /* state variables */ 36232012Smarc int cntrl; 36332012Smarc int lock; 36432012Smarc int lastcode; /* last keycode typed */ 36532012Smarc unsigned kup[8]; /* bits for each keycode*/ 36632012Smarc unsigned dkeys[8]; /* down/up mode keys */ 36732012Smarc char last; /* last character */ 368*34511Smarc } q_keyboard; 36930391Skarels 37030391Skarels 37130391Skarels /********************************************************************* 37230391Skarels * 373*34511Smarc * qdcons_init - init QDSS as console (BEFORE probe routine) 37430391Skarels * 37530391Skarels *********************************************************************/ 37630391Skarels 37730391Skarels qdcons_init() 37830391Skarels { 37930391Skarels register u_int unit; 38030391Skarels 38132012Smarc struct percpu *pcpu; /* pointer to percpu structure */ 38232012Smarc register struct qbus *qb; 38330391Skarels int *ptep; /* page table entry pointer */ 38430391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 38530391Skarels u_int mapix; /* index into QMEMmap[] array */ 38630391Skarels 38730391Skarels u_short *qdaddr; /* address of QDSS IO page CSR */ 38830391Skarels u_short *devptr; /* vitual device space */ 38932012Smarc extern cnputc(); /* standard serial console putc */ 39030391Skarels 39130391Skarels #define QDSSCSR 0x1F00 39230391Skarels 39332012Smarc /* 39432012Smarc * if console already configured, dont do again. 39532012Smarc */ 39632012Smarc if (v_putc != cnputc) 39732012Smarc return; 39832012Smarc 39930391Skarels unit = 0; 40030391Skarels 40132012Smarc /* 40232012Smarc * find the cpusw entry that matches this machine. 40332012Smarc */ 40430391Skarels 40532012Smarc for (pcpu = percpu; pcpu && pcpu->pc_cputype != cpu; pcpu++) 40632012Smarc ; 40732012Smarc if (pcpu == NULL) 40832012Smarc return; 40930391Skarels 41030391Skarels 41132012Smarc /* 41232012Smarc * Map device registers - the last 8K of umem. 41332012Smarc */ 41432012Smarc qb = (struct qbus *)pcpu->pc_io->io_details; 41532012Smarc ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize, 41632012Smarc UBAIOPAGES * NBPG); 41730391Skarels 41832012Smarc devptr = (u_short *)((char *)umem[0]+(qb->qb_memsize * NBPG)); 41930391Skarels qdaddr = (u_short *)((u_int)devptr + ubdevreg(QDSSCSR)); 42032012Smarc if (badaddr(qdaddr, sizeof(short))) { 42132012Smarc log(LOG_ERR, "Can't find qdss (badaddr)\n"); /* debug */ 42230391Skarels return(0); 42332012Smarc } 42432012Smarc /* 42532012Smarc * Map q-bus memory used by qdss. (separate map) 42632012Smarc */ 42732012Smarc mapix = QMEMSIZE - (CHUNK * (unit + 1)); 42832012Smarc phys_adr = qb->qb_maddr + mapix; 42932012Smarc ioaccess(phys_adr, QVmap[0], (CHUNK*NQD)); 43030391Skarels 43132012Smarc /* 43232012Smarc * tell QDSS which Q memory address base to decode 43332012Smarc */ 43430391Skarels 43532012Smarc /* 43632012Smarc * shifted right 16 bits - its in 64K units 43732012Smarc */ 43832012Smarc *qdaddr = (u_short)((int)mapix >> 16); 43930391Skarels qdflags[unit].config = *(u_short *)qdaddr; 44030391Skarels 44132012Smarc /* 44232012Smarc * load qdmap struct with the virtual addresses of the QDSS elements 44332012Smarc */ 44430391Skarels 44532012Smarc qdbase[unit] = (caddr_t) qvmem[0]; 44630391Skarels 44730391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 44830391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 44930391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 45030391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 45130391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 45230391Skarels qdmap[unit].red = qdbase[unit] + RED; 45330391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 45430391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 45530391Skarels 45630391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 45730391Skarels 45832012Smarc /* 45932012Smarc * init the QDSS 46032012Smarc */ 46130391Skarels 46232012Smarc /*** 46332012Smarc printf("qdbase[0] = %x, qdmap[0].memcsr = %x\n", 46432012Smarc (char *)qdbase[0], qdmap[0].memcsr); 46532012Smarc ***/ 46632012Smarc 46730391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; /* once only: turn on sync */ 46830391Skarels 46930391Skarels cursor[unit].x = 0; 47030391Skarels cursor[unit].y = 0; 47130391Skarels init_shared(unit); /* init shared memory */ 47230391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 47330391Skarels clear_qd_screen(unit); /* clear the screen */ 47430391Skarels ldfont(unit); /* load the console font */ 47530391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 47630391Skarels setup_input(unit); /* init the DUART */ 47730391Skarels 47832012Smarc v_putc = qdputc; 47932012Smarc consops = &cdevsw[QDSSMAJOR]; 48030391Skarels 48130391Skarels return(1); 48230391Skarels 48330391Skarels } /* qdcons_init */ 48430391Skarels 48530391Skarels /********************************************************************* 48630391Skarels * 48730391Skarels * qdprobe()... configure QDSS into Q memory and make it intrpt 48830391Skarels * 48930391Skarels ********************************************************************** 49030391Skarels * 49130391Skarels * calling convention: 49230391Skarels * qdprobe(reg, ctlr); 49330391Skarels * caddr_t reg; 49430391Skarels * int ctlr; 49530391Skarels * 49630391Skarels * where: reg - a character pointer to the QDSS I/O page register 49730391Skarels * ctlr - controller number (?) 49830391Skarels * 49930391Skarels * side effects: QDSS gets mapped into Qbus memory space at the first 50030391Skarels * vacant 64kb boundary counting back from the top of 50130391Skarels * Qbus memory space (qmem+4mb) 50230391Skarels * 50330391Skarels * return: QDSS bus request level and vector address returned in 50430391Skarels * registers by UNIX convention. 50530391Skarels * 50630391Skarels *****************/ 50730391Skarels 50830391Skarels qdprobe(reg) 50930391Skarels caddr_t reg; 51030391Skarels { 51132012Smarc register int br, cvec; /* value-result */ 51230391Skarels 51330391Skarels register int unit; 51430391Skarels 51530391Skarels struct dga *dga; /* pointer to gate array structure */ 51630391Skarels struct cpusw *cpup; /* pointer to the cpusw structure */ 51730391Skarels 51830391Skarels int *ptep; /* page table entry pointer */ 51930391Skarels int vector; 52030391Skarels 52130391Skarels caddr_t phys_adr; /* physical QDSS base adrs */ 52230391Skarels u_int mapix; 52330391Skarels 52432012Smarc #ifdef lint 52532012Smarc br = 0; cvec = br; br = cvec; 52632012Smarc #endif 52730391Skarels 52832012Smarc /* 52932012Smarc * calculate board unit number from I/O page register address 53032012Smarc */ 53132012Smarc 53230391Skarels unit = (int) (((int)reg >> 1) & 0x0007); 53330391Skarels 53432012Smarc /* 53530391Skarels * QDSS regs must be mapped to Qbus memory space at a 64kb physical boundary. 53630391Skarels * The Qbus memory space is mapped into the system memory space at config 53730391Skarels * time. After config runs, "qmem[0]" (ubavar.h) holds the system virtual adrs 53830391Skarels * of the start of Qbus memory. The Qbus memory page table is found via 53930391Skarels * an array of pte ptrs called "QMEMmap[]" (ubavar.h) which is also loaded at 54030391Skarels * config time. These are the variables used below to find a vacant 64kb 54130391Skarels * boundary in Qbus memory, and load it's corresponding physical adrs into 54232012Smarc * the QDSS's I/O page CSR. 54332012Smarc */ 54430391Skarels 54530391Skarels /* if this QDSS is NOT the console, then do init here.. */ 54630391Skarels 547*34511Smarc /****** XXX - REMOVED (can't test) - STILL NEED TO DO FOR NQD > 1 ***/ 54832012Smarc #ifdef notdef 54930391Skarels if (v_consputc != qdputc || unit != 0) { 55030391Skarels 55132012Smarc /* 55232012Smarc * read QDSS config info 55332012Smarc */ 55430391Skarels qdflags[unit].config = *(u_short *)reg; 55530391Skarels 55632012Smarc /* 55732012Smarc * find an empty 64kb adrs boundary 55832012Smarc */ 55930391Skarels qdbase[unit] = (caddr_t) (qmem[0] + QMEMSIZE - CHUNK); 56030391Skarels 56132012Smarc /* 56232012Smarc * find the cpusw entry that matches this machine. 56332012Smarc */ 56430391Skarels cpup = &cpusw[cpu]; 56530391Skarels while ( !(BADADDR(qdbase[unit], sizeof(short))) ) 56630391Skarels qdbase[unit] -= CHUNK; 56730391Skarels 56832012Smarc /* 56932012Smarc * tell QDSS which Q memory address base to decode 57032012Smarc */ 57130391Skarels mapix = (int) (VTOP(qdbase[unit]) - VTOP(qmem[0])); 57230391Skarels ptep = (int *) QMEMmap[0] + mapix; 57330391Skarels phys_adr = (caddr_t) (((int)*ptep & 0x001FFFFF) << PGSHIFT); 57430391Skarels *(u_short *)reg = (u_short) ((int)phys_adr >> 16); 57530391Skarels 57632012Smarc /* 57732012Smarc * load QDSS adrs map with system addresses of device regs 57832012Smarc */ 57930391Skarels qdmap[unit].template = qdbase[unit] + TMPSTART; 58030391Skarels qdmap[unit].adder = qdbase[unit] + ADDER; 58130391Skarels qdmap[unit].dga = qdbase[unit] + DGA; 58230391Skarels qdmap[unit].duart = qdbase[unit] + DUART; 58330391Skarels qdmap[unit].memcsr = qdbase[unit] + MEMCSR; 58430391Skarels qdmap[unit].red = qdbase[unit] + RED; 58530391Skarels qdmap[unit].blue = qdbase[unit] + BLUE; 58630391Skarels qdmap[unit].green = qdbase[unit] + GREEN; 58730391Skarels 58830391Skarels /* device init */ 58930391Skarels 59030391Skarels cursor[unit].x = 0; 59130391Skarels cursor[unit].y = 0; 59230391Skarels init_shared(unit); /* init shared memory */ 59330391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 59430391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 59530391Skarels setup_input(unit); /* init the DUART */ 59630391Skarels clear_qd_screen(unit); 59730391Skarels ldfont(unit); /* load the console font */ 59830391Skarels 59930391Skarels /* once only: turn on sync */ 60030391Skarels 60130391Skarels *(short *)qdmap[unit].memcsr |= SYNC_ON; 60230391Skarels } 603*34511Smarc #endif /* notdef */ 60430391Skarels 60532012Smarc /* 60632012Smarc * the QDSS interrupts at HEX vectors xx0 (DMA) xx4 (ADDER) and xx8 (DUART). 60732012Smarc * Therefore, we take three vectors from the vector pool, and then continue 60832012Smarc * to take them until we get a xx0 HEX vector. The pool provides vectors 60932012Smarc * in contiguous decending order. 61032012Smarc */ 61130391Skarels 61230391Skarels vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ 61330391Skarels 61430391Skarels while (vector & 0x0F) { /* if lo nibble != 0.. */ 61530391Skarels vector = (uba_hd[0].uh_lastiv -= 4); /* ..take another vector */ 61630391Skarels } 61730391Skarels 61832012Smarc /* 61932012Smarc * setup DGA to do a DMA interrupt (transfer count = 0) 62032012Smarc */ 62130391Skarels 62230391Skarels dga = (struct dga *) qdmap[unit].dga; 62330391Skarels 62430391Skarels dga->csr = (short) HALT; /* disable everything */ 62530391Skarels dga->ivr = (short) vector; /* load intrpt base vector */ 62630391Skarels dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ 62730391Skarels dga->bytcnt_hi = (short) 0; 62830391Skarels 62930391Skarels /* turn on DMA interrupts */ 63030391Skarels 63130391Skarels dga->csr &= ~SET_DONE_FIFO; 63230391Skarels dga->csr |= DMA_IE | DL_ENB; 63330391Skarels 63430391Skarels DELAY(20000); /* wait for the intrpt */ 63530391Skarels 63630391Skarels dga->csr = HALT; /* stop the wheels */ 63730391Skarels 63830391Skarels if (cvec != vector) /* if vector != base vector.. */ 63930391Skarels return(0); /* ..return = 'no device' */ 64030391Skarels 64130391Skarels return(sizeof(short)); /* return size of QDSS I/O page reg */ 64230391Skarels 64330391Skarels } /* qdprobe */ 64430391Skarels 64530391Skarels /***************************************************************** 64630391Skarels * 647*34511Smarc * qdattach - one-time initialization 64830391Skarels * 64930391Skarels ****************************************************************** 65030391Skarels * 65130391Skarels * calling convention: 65230391Skarels * qdattach(ui); 65330391Skarels * struct uba_device *ui; 65430391Skarels * 65530391Skarels * where: ui - pointer to the QDSS's uba_device structure 65630391Skarels * 65730391Skarels * side effects: none 65830391Skarels * return: none 65930391Skarels * 66030391Skarels *************************/ 66130391Skarels 66230391Skarels qdattach(ui) 66330391Skarels struct uba_device *ui; 66430391Skarels { 66530391Skarels register u_int unit; /* QDSS module # for this call */ 66630391Skarels 66730391Skarels unit = ui->ui_unit; /* get QDSS number */ 66830391Skarels 669*34511Smarc /* 670*34511Smarc * init "qdflags[]" for this QDSS 671*34511Smarc */ 67230391Skarels 67330391Skarels qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ 67430391Skarels qdflags[unit].mapped = 0; 67530391Skarels qdflags[unit].kernel_loop = 0; 67630391Skarels qdflags[unit].user_dma = 0; 67730391Skarels qdflags[unit].curs_acc = ACC_OFF; 67830391Skarels qdflags[unit].curs_thr = 128; 67930391Skarels qdflags[unit].tab_res = 2; /* default tablet resolution factor */ 68030391Skarels qdflags[unit].duart_imask = 0; /* init shadow variables */ 68130391Skarels qdflags[unit].adder_ie = 0; 68230391Skarels 683*34511Smarc /* 684*34511Smarc * init structures used in kbd/mouse interrupt service. This code must 685*34511Smarc * come after the "init_shared()" routine has run since that routine 686*34511Smarc * inits the eq_header[unit] structure used here. 687*34511Smarc */ 68830391Skarels 68932012Smarc /* 69032012Smarc * init the "latest mouse report" structure 69132012Smarc */ 69230391Skarels 69330391Skarels last_rep[unit].state = 0; 69430391Skarels last_rep[unit].dx = 0; 69530391Skarels last_rep[unit].dy = 0; 69630391Skarels last_rep[unit].bytcnt = 0; 69730391Skarels 698*34511Smarc /* 699*34511Smarc * init the event queue (except mouse position) 700*34511Smarc */ 70130391Skarels 70230391Skarels eq_header[unit]->header.events = (struct _vs_event *) 70330391Skarels ((int)eq_header[unit] 70430391Skarels + sizeof(struct qdinput)); 70530391Skarels 70630391Skarels eq_header[unit]->header.size = MAXEVENTS; 70730391Skarels eq_header[unit]->header.head = 0; 70830391Skarels eq_header[unit]->header.tail = 0; 70930391Skarels 71032012Smarc /* 71132012Smarc * init single process access lock switch 71232012Smarc */ 71330391Skarels 71430391Skarels one_only[unit] = 0; 71530391Skarels 71630391Skarels } /* qdattach */ 71730391Skarels 71830391Skarels /*************************************************************** 71930391Skarels * 720*34511Smarc * qdopen - open a minor device 72130391Skarels * 72230391Skarels **************************************************************** 72330391Skarels * 72430391Skarels * calling convention: qdopen(dev, flag); 72530391Skarels * dev_t dev; 72630391Skarels * int flag; 72730391Skarels * 72830391Skarels * side effects: none 72930391Skarels * 73030391Skarels *********************/ 73130391Skarels 73230391Skarels qdopen(dev, flag) 73330391Skarels dev_t dev; 73430391Skarels int flag; 73530391Skarels { 73630391Skarels register struct uba_device *ui; /* ptr to uba structures */ 73730391Skarels register struct dga *dga; /* ptr to gate array struct */ 73830391Skarels register struct tty *tp; 73932012Smarc int qdstart(); 74030391Skarels 74130391Skarels struct adder *adder; 74230391Skarels struct duart *duart; 74330391Skarels 74430391Skarels u_int unit; 74530391Skarels u_int minor_dev; 74630391Skarels int s; 74730391Skarels 74830391Skarels minor_dev = minor(dev); /* get QDSS minor device number */ 74930391Skarels unit = minor_dev >> 2; 75030391Skarels 75132012Smarc /* check for illegal conditions */ 75230391Skarels 75330391Skarels ui = qdinfo[unit]; /* get ptr to QDSS device struct */ 75430391Skarels 75530391Skarels if (ui == 0 || ui->ui_alive == 0) 75630391Skarels return(ENXIO); /* no such device or address */ 75730391Skarels 75832012Smarc /* init stuff */ 75930391Skarels 76030391Skarels adder = (struct adder *) qdmap[unit].adder; 76130391Skarels duart = (struct duart *) qdmap[unit].duart; 76230391Skarels dga = (struct dga *) qdmap[unit].dga; 76330391Skarels 76432012Smarc /* if this is the graphic device... */ 76530391Skarels 76630391Skarels if ((minor_dev & 0x03) == 2) { 76730391Skarels 76830391Skarels if (one_only[unit] != 0) 76930391Skarels return(EBUSY); 77030391Skarels else 77130391Skarels one_only[unit] = 1; 77230391Skarels 77330391Skarels qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ 77430391Skarels 77530391Skarels /* enble kbd & mouse intrpts in DUART mask reg */ 77630391Skarels 77730391Skarels qdflags[unit].duart_imask |= 0x22; 77830391Skarels duart->imask = qdflags[unit].duart_imask; 77930391Skarels 78032012Smarc /* 78132012Smarc * if the open call is to the console or the alternate console... 78232012Smarc */ 78332012Smarc } else { 78430391Skarels 78530391Skarels qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ 78630391Skarels dga->csr |= CURS_ENB; 78730391Skarels 78830391Skarels qdflags[unit].duart_imask |= 0x02; 78930391Skarels duart->imask = qdflags[unit].duart_imask; 79030391Skarels 79130391Skarels /*------------------------------- 79230391Skarels * some setup for tty handling */ 79330391Skarels 79430391Skarels tp = &qd_tty[minor_dev]; 79530391Skarels 79630391Skarels tp->t_addr = ui->ui_addr; 79730391Skarels tp->t_oproc = qdstart; 79830391Skarels 79930391Skarels if ((tp->t_state & TS_ISOPEN) == 0) { 80030391Skarels 80130391Skarels ttychars(tp); 80230391Skarels tp->t_state = TS_ISOPEN | TS_CARR_ON; 80330391Skarels tp->t_ispeed = B9600; 80430391Skarels tp->t_ospeed = B9600; 80530391Skarels 80632012Smarc if( (minor_dev & 0x03) == 0 ) { 80730391Skarels tp->t_flags = XTABS|EVENP|ECHO|CRMOD; 808*34511Smarc #ifdef POSIXTTY 809*34511Smarc tp->t_iflag = TTYDEF_IFLAG; 810*34511Smarc tp->t_oflag = TTYDEF_OFLAG; 811*34511Smarc tp->t_lflag = TTYDEF_LFLAG; 812*34511Smarc tp->t_cflag = TTYDEF_CFLAG; 813*34511Smarc #endif 81432012Smarc } 81532012Smarc else { 81630391Skarels tp->t_flags = RAW; 81732012Smarc } 81830391Skarels } 81930391Skarels 82030391Skarels /*---------------------------------------- 82130391Skarels * enable intrpts, open line discipline */ 82230391Skarels 82330391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 82430391Skarels return ((*linesw[tp->t_line].l_open)(dev, tp)); 82530391Skarels } 82630391Skarels 82730391Skarels dga->csr |= GLOBAL_IE; /* turn on the interrupts */ 82830391Skarels return(0); 82930391Skarels 83030391Skarels } /* qdopen */ 83130391Skarels 83230391Skarels /*************************************************************** 83330391Skarels * 834*34511Smarc * qdclose - clean up on the way out 83530391Skarels * 83630391Skarels **************************************************************** 83730391Skarels * 83830391Skarels * calling convention: qdclose(); 83930391Skarels * 84030391Skarels * side effects: none 84130391Skarels * 84230391Skarels * return: none 84330391Skarels * 84430391Skarels *********************/ 84530391Skarels 84630391Skarels qdclose(dev, flag) 84730391Skarels dev_t dev; 84830391Skarels int flag; 84930391Skarels { 85030391Skarels register struct tty *tp; 85130391Skarels register struct qdmap *qd; 85230391Skarels register int *ptep; 85330391Skarels int i; /* SIGNED index */ 85430391Skarels 85530391Skarels struct dga *dga; /* gate array register map pointer */ 85630391Skarels struct duart *duart; 85730391Skarels struct adder *adder; 85830391Skarels 85930391Skarels u_int unit; 86030391Skarels u_int minor_dev; 86130391Skarels u_int mapix; 86230391Skarels 86330391Skarels minor_dev = minor(dev); /* get minor device number */ 86430391Skarels unit = minor_dev >> 2; /* get QDSS number */ 86530391Skarels qd = &qdmap[unit]; 86630391Skarels 86732012Smarc /* 86832012Smarc * if this is the graphic device... 86932012Smarc */ 87030391Skarels 87130391Skarels if ((minor_dev & 0x03) == 2) { 872*34511Smarc if (one_only[unit] != 1) /* unlock driver */ 87330391Skarels return(EBUSY); 87430391Skarels else 87530391Skarels one_only[unit] = 0; 87630391Skarels 877*34511Smarc /* 878*34511Smarc * re-protect device memory 879*34511Smarc */ 88030391Skarels 88130391Skarels if (qdflags[unit].mapped & MAPDEV) { 88230391Skarels 883*34511Smarc /* TEMPLATE RAM */ 88430391Skarels 88532012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 88632012Smarc ptep = (int *)(QVmap[0] + mapix); 88730391Skarels 88830391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 88930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 89030391Skarels 891*34511Smarc /* ADDER */ 89230391Skarels 89332012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 89432012Smarc ptep = (int *)(QVmap[0] + mapix); 89530391Skarels 89630391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 89730391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 89830391Skarels 899*34511Smarc /* COLOR MAPS */ 90030391Skarels 90132012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 90232012Smarc ptep = (int *)(QVmap[0] + mapix); 90330391Skarels 90430391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 90530391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 90630391Skarels } 90730391Skarels 908*34511Smarc /* 909*34511Smarc * re-protect DMA buffer and free the map registers 910*34511Smarc */ 91130391Skarels 91230391Skarels if (qdflags[unit].mapped & MAPDMA) { 91330391Skarels 91430391Skarels dga = (struct dga *) qdmap[unit].dga; 91530391Skarels adder = (struct adder *) qdmap[unit].adder; 91630391Skarels 91730391Skarels dga->csr &= ~DMA_IE; 91830391Skarels dga->csr &= ~0x0600; /* kill DMA */ 91930391Skarels adder->command = CANCEL; 92030391Skarels 92130391Skarels /* if DMA was running, flush spurious intrpt */ 92230391Skarels 92330391Skarels if (dga->bytcnt_lo != 0) { 92430391Skarels dga->bytcnt_lo = 0; 92530391Skarels dga->bytcnt_hi = 0; 92630391Skarels DMA_SETIGNORE(DMAheader[unit]); 92730391Skarels dga->csr |= DMA_IE; 92830391Skarels dga->csr &= ~DMA_IE; 92930391Skarels } 93030391Skarels 93130391Skarels ptep = (int *) 93230391Skarels ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); 93330391Skarels 93430391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 93530391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_V | PG_KW; 93630391Skarels 93730391Skarels ubarelse(0, &Qbus_unmap[unit]); 93830391Skarels } 93930391Skarels 940*34511Smarc /* 941*34511Smarc * re-protect 1K (2 pages) event queue 942*34511Smarc */ 94330391Skarels 94430391Skarels if (qdflags[unit].mapped & MAPEQ) { 94530391Skarels 94630391Skarels ptep = (int *) 94730391Skarels ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); 94830391Skarels 94930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 95030391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 95130391Skarels } 95230391Skarels 953*34511Smarc /* 954*34511Smarc * re-protect scroll param area and disable scroll intrpts 955*34511Smarc */ 95630391Skarels 95730391Skarels if (qdflags[unit].mapped & MAPSCR) { 95830391Skarels 95930391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 96030391Skarels + (mfpr(SBR) | 0x80000000)); 96130391Skarels 96230391Skarels /* re-protect 512 scroll param area */ 96330391Skarels 96430391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 96530391Skarels 96630391Skarels adder = (struct adder *) qdmap[unit].adder; 96730391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 96830391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 96930391Skarels } 97030391Skarels 971*34511Smarc /* 972*34511Smarc * re-protect color map write buffer area and kill intrpts 973*34511Smarc */ 97430391Skarels 97530391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 97630391Skarels 97730391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 97830391Skarels + (mfpr(SBR) | 0x80000000)); 97930391Skarels 98030391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 98130391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 98230391Skarels 98330391Skarels color_buf[unit]->status = 0; 98430391Skarels 98530391Skarels adder = (struct adder *) qdmap[unit].adder; 98630391Skarels qdflags[unit].adder_ie &= ~VSYNC; 98730391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 98830391Skarels } 98930391Skarels 990*34511Smarc /* 991*34511Smarc * flag that everthing is unmapped 992*34511Smarc */ 99330391Skarels 994*34511Smarc mtpr(TBIA, 0); /* invalidate translation buf */ 995*34511Smarc qdflags[unit].mapped = 0; /* flag everything unmapped */ 99630391Skarels qdflags[unit].inuse &= ~GRAPHIC_DEV; 99730391Skarels qdflags[unit].curs_acc = ACC_OFF; 99830391Skarels qdflags[unit].curs_thr = 128; 99930391Skarels 1000*34511Smarc /* 1001*34511Smarc * restore the console 1002*34511Smarc */ 100330391Skarels 100430391Skarels dga = (struct dga *) qdmap[unit].dga; 100530391Skarels adder = (struct adder *) qdmap[unit].adder; 100630391Skarels 100730391Skarels dga->csr &= ~DMA_IE; 100830391Skarels dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ 100930391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 101030391Skarels adder->command = CANCEL; 101130391Skarels 101230391Skarels /* if DMA was running, flush spurious intrpt */ 101330391Skarels 101430391Skarels if (dga->bytcnt_lo != 0) { 101530391Skarels dga->bytcnt_lo = 0; 101630391Skarels dga->bytcnt_hi = 0; 101730391Skarels DMA_SETIGNORE(DMAheader[unit]); 101830391Skarels dga->csr |= DMA_IE; 101930391Skarels dga->csr &= ~DMA_IE; 102030391Skarels } 102130391Skarels 102230391Skarels init_shared(unit); /* init shared memory */ 102330391Skarels setup_dragon(unit); /* init ADDER/VIPER */ 102430391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 102530391Skarels setup_input(unit); /* init the DUART */ 102630391Skarels ldfont(unit); 102730391Skarels cursor[unit].x = 0; 102830391Skarels cursor[unit].y = 0; 102930391Skarels 1030*34511Smarc /* 1031*34511Smarc * shut off the mouse rcv intrpt and turn on kbd intrpts 1032*34511Smarc */ 103330391Skarels duart = (struct duart *) qdmap[unit].duart; 103430391Skarels qdflags[unit].duart_imask &= ~(0x20); 103530391Skarels qdflags[unit].duart_imask |= 0x02; 103630391Skarels duart->imask = qdflags[unit].duart_imask; 1037*34511Smarc /* 1038*34511Smarc * shut off interrupts if all is closed 1039*34511Smarc */ 104030391Skarels if (!(qdflags[unit].inuse & (CONS_DEV | ALTCONS_DEV))) { 104130391Skarels dga = (struct dga *) qdmap[unit].dga; 104230391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 104330391Skarels } 104430391Skarels } 1045*34511Smarc else { /* if this is the console or the alternate console */ 104630391Skarels tp = &qd_tty[minor_dev]; 104730391Skarels 104830391Skarels (*linesw[tp->t_line].l_close)(tp); 104930391Skarels ttyclose(tp); 105030391Skarels tp->t_state = 0; 105130391Skarels qdflags[unit].inuse &= ~CONS_DEV; 1052*34511Smarc /* 1053*34511Smarc * if graphics device is closed, kill interrupts 1054*34511Smarc */ 105530391Skarels if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { 105630391Skarels dga = (struct dga *) qdmap[unit].dga; 105730391Skarels dga->csr &= ~(GLOBAL_IE | DMA_IE); 105830391Skarels } 105930391Skarels } 106030391Skarels 106130391Skarels return(0); 106230391Skarels 106330391Skarels } /* qdclose */ 106430391Skarels 106530391Skarels /*************************************************************** 106630391Skarels * 1067*34511Smarc * qdioctl - provide QDSS control services 106830391Skarels * 106930391Skarels **************************************************************** 107030391Skarels * 107130391Skarels * calling convention: qdioctl(dev, cmd, datap, flags); 107230391Skarels * 107330391Skarels * where: dev - the major/minor device number 107430391Skarels * cmd - the user-passed command argument 107530391Skarels * datap - ptr to user input buff (128 bytes max) 107630391Skarels * flags - "f_flags" from "struct file" in file.h 107730391Skarels * 107830391Skarels * 107930391Skarels * - here is the format for the input "cmd" argument 108030391Skarels * 108130391Skarels * 31 29 28 23 22 16 15 8 7 0 108230391Skarels * +----------------------------------------------------------------+ 108330391Skarels * |I/O type| | buff length | device ID char | user command | 108430391Skarels * +----------------------------------------------------------------+ 108530391Skarels * 108630391Skarels * Return data is in the data buffer pointed to by "datap" input spec 108730391Skarels * 108830391Skarels *********************/ 108930391Skarels 109030391Skarels qdioctl(dev, cmd, datap, flags) 109130391Skarels dev_t dev; 109230391Skarels int cmd; 109330391Skarels caddr_t datap; 109430391Skarels int flags; 109530391Skarels { 109630391Skarels register int *ptep; /* page table entry pointer */ 109732012Smarc register int mapix; /* QVmap[] page table index */ 109830391Skarels register struct _vs_event *event; 109930391Skarels register struct tty *tp; 110030391Skarels 110130391Skarels struct qdmap *qd; /* pointer to device map struct */ 110230391Skarels struct dga *dga; /* Gate Array reg structure pntr */ 110330391Skarels struct duart *duart; /* DUART reg structure pointer */ 110430391Skarels struct adder *adder; /* ADDER reg structure pointer */ 110530391Skarels 110630391Skarels struct prgkbd *cmdbuf; 110730391Skarels struct prg_cursor *curs; 110830391Skarels struct _vs_cursor *pos; 110930391Skarels 111030391Skarels u_int unit = minor(dev) >> 2; /* number of caller's QDSS */ 111130391Skarels u_int minor_dev = minor(dev); 111230391Skarels struct uba_device *ui = qdinfo[unit]; 111330391Skarels struct qd_softc *sc = &qd_softc[ui->ui_unit]; 111432012Smarc /* struct devget *devget; */ 111530391Skarels 111630391Skarels int error; 111730391Skarels int s; 111830391Skarels 111930391Skarels int i; /* SIGNED index */ 112030391Skarels int sbr; /* SBR variable (you silly boy) */ 112130391Skarels u_int ix; 112230391Skarels 112330391Skarels short status; 112430391Skarels short *shortp; /* generic pointer to a short */ 112530391Skarels char *chrp; /* generic character pointer */ 112630391Skarels 112730391Skarels short *temp; /* a pointer to template RAM */ 112830391Skarels 112932012Smarc /* service graphic device ioctl commands */ 113030391Skarels switch (cmd) { 1131*34511Smarc /* 1132*34511Smarc * extract the oldest event from the event queue 1133*34511Smarc */ 113430391Skarels case QD_GETEVENT: 113530391Skarels if (ISEMPTY(eq_header[unit])) { 113630391Skarels event = (struct _vs_event *) datap; 113730391Skarels event->vse_device = VSE_NULL; 113830391Skarels break; 113930391Skarels } 114030391Skarels event = (struct _vs_event *) GETBEGIN(eq_header[unit]); 114132012Smarc s = spltty(); 114230391Skarels GETEND(eq_header[unit]); 114330391Skarels splx(s); 114430391Skarels bcopy(event, datap, sizeof(struct _vs_event)); 114530391Skarels break; 114630391Skarels 114730391Skarels /*------------------------------------------------------- 114830391Skarels * init the dragon stuff, DUART, and driver variables */ 114930391Skarels 115030391Skarels case QD_RESET: 115130391Skarels 115230391Skarels init_shared(unit); /* init shared memory */ 115330391Skarels setup_dragon(unit); /* init the ADDER/VIPER stuff */ 115430391Skarels clear_qd_screen(unit); 115530391Skarels ldcursor(unit, cons_cursor); /* load default cursor map */ 115630391Skarels ldfont(unit); /* load the console font */ 115730391Skarels setup_input(unit); /* init the DUART */ 115830391Skarels break; 115930391Skarels 116030391Skarels /*---------------------------------------- 116130391Skarels * init the DUART and driver variables */ 116230391Skarels 116330391Skarels case QD_SET: 116430391Skarels 116530391Skarels init_shared(unit); 116630391Skarels setup_input(unit); 116730391Skarels break; 116830391Skarels 116930391Skarels /*--------------------------------------------------------------- 117030391Skarels * clear the QDSS screen. (NOTE that this reinits the dragon) */ 117130391Skarels 117230391Skarels case QD_CLRSCRN: 117330391Skarels 117430391Skarels setup_dragon(unit); 117530391Skarels clear_qd_screen(unit); 117630391Skarels break; 117730391Skarels 117830391Skarels /*------------------------------------ 117930391Skarels * load a cursor into template RAM */ 118030391Skarels 118130391Skarels case QD_WTCURSOR: 118230391Skarels 118330391Skarels ldcursor(unit, datap); 118430391Skarels break; 118530391Skarels 118630391Skarels case QD_RDCURSOR: 118730391Skarels 118830391Skarels temp = (short *) qdmap[unit].template; 118930391Skarels 119030391Skarels /* cursor is 32 WORDS from the end of the 8k WORD... 119130391Skarels * ...template space */ 119230391Skarels 119330391Skarels temp += (8 * 1024) - 32; 119430391Skarels 119530391Skarels for (i = 0; i < 32; ++i, datap += sizeof(short)) 119630391Skarels *(short *)datap = *temp++; 119730391Skarels break; 119830391Skarels 119930391Skarels /*------------------------------ 120030391Skarels * position the mouse cursor */ 120130391Skarels 120230391Skarels case QD_POSCURSOR: 120330391Skarels 120430391Skarels dga = (struct dga *) qdmap[unit].dga; 120530391Skarels pos = (struct _vs_cursor *) datap; 120632012Smarc s = spltty(); 120730391Skarels dga->x_cursor = TRANX(pos->x); 120830391Skarels dga->y_cursor = TRANY(pos->y); 120930391Skarels eq_header[unit]->curs_pos.x = pos->x; 121030391Skarels eq_header[unit]->curs_pos.y = pos->y; 121130391Skarels splx(s); 121230391Skarels break; 121330391Skarels 121430391Skarels /*-------------------------------------- 121530391Skarels * set the cursor acceleration factor */ 121630391Skarels 121730391Skarels case QD_PRGCURSOR: 121830391Skarels 121930391Skarels curs = (struct prg_cursor *) datap; 122032012Smarc s = spltty(); 122130391Skarels qdflags[unit].curs_acc = curs->acc_factor; 122230391Skarels qdflags[unit].curs_thr = curs->threshold; 122330391Skarels splx(s); 122430391Skarels break; 122530391Skarels 122630391Skarels /*--------------------------------------- 122730391Skarels * enable 'user write' to device pages */ 122830391Skarels 122930391Skarels case QD_MAPDEVICE: 123030391Skarels 123130391Skarels /*-------------- 123230391Skarels * init stuff */ 123330391Skarels 123430391Skarels qdflags[unit].mapped |= MAPDEV; 123530391Skarels qd = (struct qdmap *) &qdmap[unit]; 123630391Skarels 123730391Skarels /*------------------------------------- 123830391Skarels * enable user write to template RAM */ 123930391Skarels 124032012Smarc mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); 124132012Smarc ptep = (int *)(QVmap[0] + mapix); 124230391Skarels 124330391Skarels for (i = VTOP(TMPSIZE); i > 0; --i) 124430391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 124530391Skarels 124630391Skarels /*---------------------------------- 124730391Skarels * enable user write to registers */ 124830391Skarels 124932012Smarc mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); 125032012Smarc ptep = (int *)(QVmap[0] + mapix); 125130391Skarels 125230391Skarels for (i = VTOP(REGSIZE); i > 0; --i) 125330391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 125430391Skarels 125530391Skarels /*----------------------------------- 125630391Skarels * enable user write to color maps */ 125730391Skarels 125832012Smarc mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); 125932012Smarc ptep = (int *)(QVmap[0] + mapix); 126030391Skarels 126130391Skarels for (i = VTOP(CLRSIZE); i > 0; --i) 126230391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 126330391Skarels 126430391Skarels /*------------------------------ 126530391Skarels * enable user write to DUART */ 126630391Skarels 126732012Smarc mapix = VTOP((int)qd->duart) - VTOP(qvmem[0]); 126832012Smarc ptep = (int *)(QVmap[0] + mapix); 126930391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ 127030391Skarels 127130391Skarels mtpr(TBIA, 0); /* smash CPU's translation buffer */ 127230391Skarels 127330391Skarels /*------------------------------------------ 127430391Skarels * stuff qdmap structure in return buffer */ 127530391Skarels 127630391Skarels bcopy(qd, datap, sizeof(struct qdmap)); 127730391Skarels break; 127830391Skarels 127930391Skarels /*------------------------------------- 128030391Skarels * do setup for DMA by user process */ 128130391Skarels 128230391Skarels case QD_MAPIOBUF: 128330391Skarels 128430391Skarels /*------------------------------------------------ 128530391Skarels * set 'user write enable' bits for DMA buffer */ 128630391Skarels 128730391Skarels qdflags[unit].mapped |= MAPDMA; 128830391Skarels 128930391Skarels ptep = (int *) ((VTOP(DMAheader[unit]) * 4) 129030391Skarels + (mfpr(SBR) | 0x80000000)); 129130391Skarels 129230391Skarels for (i = (DMAbuf_size >> PGSHIFT); i > 0; --i) 129330391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 129430391Skarels 129530391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 129630391Skarels 129730391Skarels /*------------------------------------- 129830391Skarels * set up QBUS map registers for DMA */ 129930391Skarels 130030391Skarels DMAheader[unit]->QBAreg = 130130391Skarels uballoc(0, DMAheader[unit], DMAbuf_size, 0); 130230391Skarels 130330391Skarels if (DMAheader[unit]->QBAreg == 0) 1304*34511Smarc printf("qd%d: qdioctl: QBA setup error\n", unit); 130530391Skarels 130630391Skarels Qbus_unmap[unit] = DMAheader[unit]->QBAreg; 130730391Skarels DMAheader[unit]->QBAreg &= 0x3FFFF; 130830391Skarels 130930391Skarels /*---------------------- 131030391Skarels * return I/O buf adr */ 131130391Skarels 131230391Skarels *(int *)datap = (int) DMAheader[unit]; 131330391Skarels break; 131430391Skarels 131530391Skarels /*---------------------------------------------------------------- 131630391Skarels * map the shared scroll param area and enable scroll interpts */ 131730391Skarels 131830391Skarels case QD_MAPSCROLL: 131930391Skarels 132030391Skarels qdflags[unit].mapped |= MAPSCR; 132130391Skarels 132230391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 132330391Skarels + (mfpr(SBR) | 0x80000000)); 132430391Skarels 132530391Skarels /* allow user write to scroll area */ 132630391Skarels 132730391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 132830391Skarels 132930391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 133030391Skarels 133130391Skarels scroll[unit]->status = 0; 133230391Skarels 133330391Skarels adder = (struct adder *) qdmap[unit].adder; 133430391Skarels 133530391Skarels qdflags[unit].adder_ie |= FRAME_SYNC; 133630391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 133730391Skarels 133830391Skarels /* return scroll area address */ 133930391Skarels 134030391Skarels *(int *)datap = (int) scroll[unit]; 134130391Skarels break; 134230391Skarels 134330391Skarels /*------------------------------------------------------------- 134430391Skarels * unmap shared scroll param area and disable scroll intrpts */ 134530391Skarels 134630391Skarels case QD_UNMAPSCROLL: 134730391Skarels 134830391Skarels if (qdflags[unit].mapped & MAPSCR) { 134930391Skarels 135030391Skarels qdflags[unit].mapped &= ~MAPSCR; 135130391Skarels 135230391Skarels ptep = (int *) ((VTOP(scroll[unit]) * 4) 135330391Skarels + (mfpr(SBR) | 0x80000000)); 135430391Skarels 135530391Skarels /* re-protect 512 scroll param area */ 135630391Skarels 135730391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 135830391Skarels 135930391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 136030391Skarels 136130391Skarels adder = (struct adder *) qdmap[unit].adder; 136230391Skarels qdflags[unit].adder_ie &= ~FRAME_SYNC; 136330391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 136430391Skarels } 136530391Skarels break; 136630391Skarels 136730391Skarels /*----------------------------------------------------------- 136830391Skarels * map shared color map write buf and turn on vsync intrpt */ 136930391Skarels 137030391Skarels case QD_MAPCOLOR: 137130391Skarels 137230391Skarels qdflags[unit].mapped |= MAPCOLOR; 137330391Skarels 137430391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 137530391Skarels + (mfpr(SBR) | 0x80000000)); 137630391Skarels 137730391Skarels /* allow user write to color map write buffer */ 137830391Skarels 137930391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 138030391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 138130391Skarels 138230391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 138330391Skarels 138430391Skarels adder = (struct adder *) qdmap[unit].adder; 138530391Skarels 138630391Skarels qdflags[unit].adder_ie |= VSYNC; 138730391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 138830391Skarels 138930391Skarels /* return scroll area address */ 139030391Skarels 139130391Skarels *(int *)datap = (int) color_buf[unit]; 139230391Skarels break; 139330391Skarels 139430391Skarels /*-------------------------------------------------------------- 139530391Skarels * unmap shared color map write buffer and kill VSYNC intrpts */ 139630391Skarels 139730391Skarels case QD_UNMAPCOLOR: 139830391Skarels 139930391Skarels if (qdflags[unit].mapped & MAPCOLOR) { 140030391Skarels 140130391Skarels qdflags[unit].mapped &= ~MAPCOLOR; 140230391Skarels 140330391Skarels ptep = (int *) ((VTOP(color_buf[unit]) * 4) 140430391Skarels + (mfpr(SBR) | 0x80000000)); 140530391Skarels 140630391Skarels /* re-protect color map write buffer */ 140730391Skarels 140830391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; 140930391Skarels *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; 141030391Skarels 141130391Skarels mtpr(TBIA, 0); /* smash CPU's translation buf */ 141230391Skarels 141330391Skarels adder = (struct adder *) qdmap[unit].adder; 141430391Skarels 141530391Skarels qdflags[unit].adder_ie &= ~VSYNC; 141630391Skarels adder->interrupt_enable = qdflags[unit].adder_ie; 141730391Skarels } 141830391Skarels break; 141930391Skarels 142030391Skarels /*--------------------------------------------- 142130391Skarels * give user write access to the event queue */ 142230391Skarels 142330391Skarels case QD_MAPEVENT: 142430391Skarels 142530391Skarels qdflags[unit].mapped |= MAPEQ; 142630391Skarels 142730391Skarels ptep = (int *) ((VTOP(eq_header[unit]) * 4) 142830391Skarels + (mfpr(SBR) | 0x80000000)); 142930391Skarels 143030391Skarels /* allow user write to 1K event queue */ 143130391Skarels 143230391Skarels *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; 143330391Skarels *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; 143430391Skarels 143530391Skarels mtpr(TBIA, 0); /* clr CPU translation buf */ 143630391Skarels 143730391Skarels /* return event queue address */ 143830391Skarels 143930391Skarels *(int *)datap = (int) eq_header[unit]; 144030391Skarels break; 144130391Skarels 144230391Skarels /*----------------------------------------------- 144330391Skarels * pass caller's programming commands to LK201 */ 144430391Skarels 144530391Skarels case QD_PRGKBD: 144630391Skarels 144730391Skarels duart = (struct duart *) qdmap[unit].duart; 144830391Skarels cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ 144930391Skarels 145030391Skarels /*---------------- 145130391Skarels * send command */ 145230391Skarels 145330391Skarels for (i = 1000; i > 0; --i) { 145430391Skarels if ((status = duart->statusA) & XMT_RDY) { 145530391Skarels duart->dataA = cmdbuf->cmd; 145630391Skarels break; 145730391Skarels } 145830391Skarels } 145930391Skarels 146030391Skarels if (i == 0) { 1461*34511Smarc printf("qd%d: qdioctl: timeout on XMT_RDY [1]\n", unit); 146230391Skarels break; 146330391Skarels } 146430391Skarels 146530391Skarels /*---------------- 146630391Skarels * send param1? */ 146730391Skarels 146830391Skarels if (cmdbuf->cmd & LAST_PARAM) 146930391Skarels break; 147030391Skarels 147130391Skarels for (i = 1000; i > 0; --i) { 147230391Skarels if ((status = duart->statusA) & XMT_RDY) { 147330391Skarels duart->dataA = cmdbuf->param1; 147430391Skarels break; 147530391Skarels } 147630391Skarels } 147730391Skarels 147830391Skarels if (i == 0) { 1479*34511Smarc printf("\nqd%d: qdioctl: timeout on XMT_RDY [2]\n", unit); 148030391Skarels break; 148130391Skarels } 148230391Skarels 148330391Skarels /*---------------- 148430391Skarels * send param2? */ 148530391Skarels 148630391Skarels if (cmdbuf->param1 & LAST_PARAM) 148730391Skarels break; 148830391Skarels 148930391Skarels for (i = 1000; i > 0; --i) { 149030391Skarels if ((status = duart->statusA) & XMT_RDY) { 149130391Skarels duart->dataA = cmdbuf->param2; 149230391Skarels break; 149330391Skarels } 149430391Skarels } 149530391Skarels 149630391Skarels if (i == 0) { 1497*34511Smarc printf("qd%d: qdioctl: timeout on XMT_RDY [3]\n", unit); 149830391Skarels break; 149930391Skarels } 150030391Skarels 150130391Skarels break; 150230391Skarels 150330391Skarels /*---------------------------------------------------- 150430391Skarels * pass caller's programming commands to the mouse */ 150530391Skarels 150630391Skarels case QD_PRGMOUSE: 150730391Skarels 150830391Skarels duart = (struct duart *) qdmap[unit].duart; 150930391Skarels 151030391Skarels for (i = 1000; i > 0; --i) { 151130391Skarels if ((status = duart->statusB) & XMT_RDY) { 151230391Skarels duart->dataB = *datap; 151330391Skarels break; 151430391Skarels } 151530391Skarels } 151630391Skarels 151730391Skarels if (i == 0) { 1518*34511Smarc printf("qd%d: qdioctl: timeout on XMT_RDY [4]\n", unit); 151930391Skarels } 152030391Skarels 152130391Skarels break; 152230391Skarels 152330391Skarels /*---------------------------------------------- 152430391Skarels * get QDSS configuration word and return it */ 152530391Skarels 152630391Skarels case QD_RDCONFIG: 152730391Skarels 152830391Skarels *(short *)datap = qdflags[unit].config; 152930391Skarels break; 153030391Skarels 153130391Skarels /*---------------------- 153230391Skarels * program the tablet */ 153330391Skarels 153430391Skarels case QD_PRGTABLET: 153530391Skarels 153630391Skarels duart = (struct duart *) qdmap[unit].duart; 153730391Skarels 153830391Skarels for (i = 1000; i > 0; --i) { 153930391Skarels if ((status = duart->statusB) & XMT_RDY) { 154030391Skarels duart->dataB = *datap; 154130391Skarels break; 154230391Skarels } 154330391Skarels } 154430391Skarels 154530391Skarels if (i == 0) { 1546*34511Smarc printf("qd%d: qdioctl: timeout on XMT_RDY [5]\n", unit); 154730391Skarels } 154830391Skarels 154930391Skarels break; 155030391Skarels 155130391Skarels /*----------------------------------------------- 155230391Skarels * program the tablet report resolution factor */ 155330391Skarels 155430391Skarels case QD_PRGTABRES: 155530391Skarels 155630391Skarels qdflags[unit].tab_res = *(short *)datap; 155730391Skarels break; 155830391Skarels 155930391Skarels default: 156030391Skarels /*----------------------------- 156130391Skarels * service tty type ioctl's */ 156230391Skarels 156330391Skarels if (!(minor_dev & 0x02)) { 156430391Skarels 156530391Skarels tp = &qd_tty[minor_dev]; 156630391Skarels 156730391Skarels error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); 156830391Skarels if (error >= 0) { 156930391Skarels return(error); 157030391Skarels } 157130391Skarels 157230391Skarels error = ttioctl(tp, cmd, datap, flags); 157330391Skarels if (error >= 0) { 157430391Skarels return(error); 157530391Skarels } 157630391Skarels } 157730391Skarels break; 157830391Skarels } 157930391Skarels 158030391Skarels /*-------------------------------- 158130391Skarels * clean up and get outta here */ 158230391Skarels 158330391Skarels return(0); 158430391Skarels 158530391Skarels } /* qdioctl */ 158630391Skarels 158730391Skarels /********************************************************************** 158830391Skarels * 158930391Skarels * qdselect()... service select call for event queue input 159030391Skarels * 159130391Skarels **********************************************************************/ 159230391Skarels 159330391Skarels qdselect(dev, rw) 159430391Skarels dev_t dev; 159530391Skarels int rw; 159630391Skarels { 159730391Skarels register int s; 159830391Skarels register int unit; 159930391Skarels 160032012Smarc s = spltty(); 160130391Skarels unit = minor(dev) >> 2; 160230391Skarels 160330391Skarels switch (rw) { 160430391Skarels 160530391Skarels case FREAD: /* event available? */ 160630391Skarels 160730391Skarels if(!(ISEMPTY(eq_header[unit]))) { 160830391Skarels splx(s); 160930391Skarels return(1); /* return "1" if event exists */ 161030391Skarels } 161130391Skarels rsel[unit] = u.u_procp; 161230391Skarels qdflags[unit].selmask |= SEL_READ; 161330391Skarels splx(s); 161430391Skarels return(0); 161530391Skarels 161630391Skarels case FWRITE: /* DMA done? */ 161730391Skarels 161830391Skarels if (DMA_ISEMPTY(DMAheader[unit])) { 161930391Skarels splx(s); 162030391Skarels return(1); /* return "1" if DMA is done */ 162130391Skarels } 162230391Skarels rsel[unit] = u.u_procp; 162330391Skarels qdflags[unit].selmask |= SEL_WRITE; 162430391Skarels splx(s); 162530391Skarels return(0); 162630391Skarels } 162730391Skarels 162830391Skarels } /* qdselect() */ 162930391Skarels 163030391Skarels /*************************************************************** 163130391Skarels * 163230391Skarels * qdwrite()... output to the QDSS screen as a TTY 163330391Skarels * 163430391Skarels ***************************************************************/ 163530391Skarels 163630391Skarels extern qd_strategy(); 163730391Skarels 163830391Skarels qdwrite(dev, uio) 163930391Skarels dev_t dev; 164030391Skarels struct uio *uio; 164130391Skarels { 164230391Skarels register struct tty *tp; 164330391Skarels register int minor_dev; 164430391Skarels register int unit; 164530391Skarels 164630391Skarels minor_dev = minor(dev); 164730391Skarels unit = (minor_dev >> 2) & 0x07; 164830391Skarels 164930391Skarels /*------------------------------ 165030391Skarels * if this is the console... */ 165130391Skarels 165230391Skarels if ((minor_dev & 0x03) != 0x02 && 165330391Skarels qdflags[unit].inuse & CONS_DEV) { 165430391Skarels tp = &qd_tty[minor_dev]; 165530391Skarels return ((*linesw[tp->t_line].l_write)(tp, uio)); 165630391Skarels } 165730391Skarels 165830391Skarels /*------------------------------------------------ 165930391Skarels * else this must be a DMA xfer from user space */ 166030391Skarels 166130391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 166230391Skarels return (physio(qd_strategy, &qdbuf[unit], 166330391Skarels dev, B_WRITE, minphys, uio)); 166430391Skarels } 166530391Skarels } 166630391Skarels 166730391Skarels /*************************************************************** 166830391Skarels * 166930391Skarels * qdread()... read from QDSS keyboard as a TTY 167030391Skarels * 167130391Skarels ***************************************************************/ 167230391Skarels 167330391Skarels qdread(dev, uio) 167430391Skarels dev_t dev; 167530391Skarels struct uio *uio; 167630391Skarels { 167730391Skarels register struct tty *tp; 167830391Skarels register int minor_dev; 167930391Skarels register int unit; 168030391Skarels 168130391Skarels minor_dev = minor(dev); 168230391Skarels unit = (minor_dev >> 2) & 0x07; 168330391Skarels 168430391Skarels /*------------------------------ 168530391Skarels * if this is the console... */ 168630391Skarels 168730391Skarels if ((minor_dev & 0x03) != 0x02 && 168830391Skarels qdflags[unit].inuse & CONS_DEV) { 168930391Skarels tp = &qd_tty[minor_dev]; 169030391Skarels return ((*linesw[tp->t_line].l_read)(tp, uio)); 169130391Skarels } 169230391Skarels 169330391Skarels /*------------------------------------------------ 169430391Skarels * else this must be a bitmap-to-processor xfer */ 169530391Skarels 169630391Skarels else if (qdflags[unit].inuse & GRAPHIC_DEV) { 169730391Skarels return (physio(qd_strategy, &qdbuf[unit], 169830391Skarels dev, B_READ, minphys, uio)); 169930391Skarels } 170030391Skarels } 170130391Skarels 170230391Skarels /*************************************************************** 170330391Skarels * 170430391Skarels * qd_strategy()... strategy routine to do DMA 170530391Skarels * 170630391Skarels ***************************************************************/ 170730391Skarels 170830391Skarels qd_strategy(bp) 170930391Skarels register struct buf *bp; 171030391Skarels { 171130391Skarels register struct dga *dga; 171230391Skarels register struct adder *adder; 171330391Skarels 171430391Skarels char *DMAbufp; 171530391Skarels 171630391Skarels int QBAreg; 171730391Skarels int bytcnt; 171830391Skarels int s; 171930391Skarels int unit; 172030391Skarels int cookie; 172130391Skarels 172230391Skarels int i,j,k; 172330391Skarels 172430391Skarels unit = (minor(bp->b_dev) >> 2) & 0x07; 172530391Skarels 172632012Smarc /* 172732012Smarc * init pointers 172832012Smarc */ 172930391Skarels 173030391Skarels if ((QBAreg = ubasetup(0, bp, 0)) == 0) { 1731*34511Smarc printf("qd%d: qd_strategy: QBA setup error\n", unit); 173230391Skarels goto STRAT_ERR; 173330391Skarels } 173430391Skarels 173530391Skarels dga = (struct dga *) qdmap[unit].dga; 173630391Skarels 173732012Smarc s = spltty(); 173830391Skarels 173930391Skarels qdflags[unit].user_dma = -1; 174030391Skarels 174130391Skarels dga->csr |= DMA_IE; 174230391Skarels 174330391Skarels cookie = QBAreg & 0x3FFFF; 174430391Skarels dga->adrs_lo = (short) cookie; 174530391Skarels dga->adrs_hi = (short) (cookie >> 16); 174630391Skarels 174730391Skarels dga->bytcnt_lo = (short) bp->b_bcount; 174830391Skarels dga->bytcnt_hi = (short) (bp->b_bcount >> 16); 174930391Skarels 175030391Skarels while (qdflags[unit].user_dma) { 175130391Skarels sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); 175230391Skarels } 175330391Skarels 175430391Skarels splx(s); 175530391Skarels ubarelse(0, &QBAreg); 175630391Skarels 175730391Skarels if (!(dga->csr & DMA_ERR)) { 175830391Skarels iodone(bp); 175930391Skarels return; 176030391Skarels } 176130391Skarels 176230391Skarels STRAT_ERR: 176330391Skarels adder = (struct adder *) qdmap[unit].adder; 176430391Skarels adder->command = CANCEL; /* cancel adder activity */ 176530391Skarels dga->csr &= ~DMA_IE; 176630391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 176730391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 176830391Skarels bp->b_flags |= B_ERROR; /* flag an error to physio() */ 176930391Skarels 177030391Skarels /* if DMA was running, flush spurious intrpt */ 177130391Skarels 177230391Skarels if (dga->bytcnt_lo != 0) { 177330391Skarels dga->bytcnt_lo = 0; 177430391Skarels dga->bytcnt_hi = 0; 177530391Skarels DMA_SETIGNORE(DMAheader[unit]); 177630391Skarels dga->csr |= DMA_IE; 177730391Skarels } 177830391Skarels 177930391Skarels iodone(bp); 178030391Skarels 178130391Skarels } /* qd_strategy */ 178230391Skarels 178330391Skarels /******************************************************************* 178430391Skarels * 178530391Skarels * qdstart()... startup output to the console screen 178630391Skarels * 178730391Skarels ******************************************************************** 1788*34511Smarc * NOTE - You must have tty.c fixed so it doesn't try to sleep 1789*34511Smarc * waiting for a transmitter interrupt (which would never occur). 1790*34511Smarc * Writes to the QDSS are synchronous and have (essentially) 1791*34511Smarc * completed by the time the start routine returns. 179230391Skarels * 179330391Skarels * calling convention: 179430391Skarels * 179530391Skarels * qdstart(tp); 1796*34511Smarc * struct tty *tp; # pointer to tty structure 179730391Skarels * 179830391Skarels ********/ 179930391Skarels 180030391Skarels qdstart(tp) 180130391Skarels register struct tty *tp; 180230391Skarels { 180330391Skarels register int which_unit, unit, c; 180430391Skarels int s; 180530391Skarels 180630391Skarels unit = minor(tp->t_dev); 180730391Skarels which_unit = (unit >> 2) & 0x3; 1808*34511Smarc /* unit &= 0x03; */ 180930391Skarels 1810*34511Smarc /* If it's currently active, or delaying, no need to do anything. */ 181132012Smarc s = spltty(); 181230391Skarels if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 181330391Skarels goto out; 181430391Skarels 181532012Smarc /* 1816*34511Smarc * XXX - this loop is at spltty. not good, but hardly worth 1817*34511Smarc * fixing since the glass tty is only used when the window 1818*34511Smarc * system isn't running. if you debug window systems you 1819*34511Smarc * might want to rethink this. 182032012Smarc */ 182130391Skarels while (tp->t_outq.c_cc) { 1822*34511Smarc c = getc(&tp->t_outq); 1823*34511Smarc blitc(which_unit, c & 0xFF); 182430391Skarels } 1825*34511Smarc tp->t_state &= ~TS_BUSY; 1826*34511Smarc if (tp->t_state&TS_ASLEEP) { 1827*34511Smarc tp->t_state &= ~TS_ASLEEP; 1828*34511Smarc wakeup((caddr_t)&tp->t_outq); 182930391Skarels } 183030391Skarels 183130391Skarels out: 183230391Skarels splx(s); 183330391Skarels 183430391Skarels } /* qdstart */ 183530391Skarels 183630391Skarels 183730391Skarels /******************************************************************* 183830391Skarels * 183930391Skarels * qdstop()... stop the tty 184030391Skarels * 184130391Skarels *******************************************************************/ 184230391Skarels 184330391Skarels qdstop(tp, flag) 184430391Skarels register struct tty *tp; 184530391Skarels int flag; 184630391Skarels { 184730391Skarels register int s; 184830391Skarels 1849*34511Smarc #ifdef notdef /* not needed - qdss is synchronous */ 185032012Smarc s = spltty(); /* block intrpts during state modification */ 185130391Skarels if (tp->t_state & TS_BUSY) { 185230391Skarels if ((tp->t_state & TS_TTSTOP) == 0) { 185330391Skarels tp->t_state |= TS_FLUSH; 185430391Skarels } else 185530391Skarels tp->t_state &= ~TS_BUSY; 185630391Skarels } 185730391Skarels splx(s); 1858*34511Smarc #endif 185930391Skarels } 186030391Skarels 186130391Skarels /******************************************************************* 186230391Skarels * 186330391Skarels * blitc()... output a character to the QDSS screen 186430391Skarels * 186530391Skarels ******************************************************************** 186630391Skarels * 186730391Skarels * calling convention: 186830391Skarels * 186930391Skarels * blitc(chr); 187030391Skarels * char chr; ;character to be displayed 187130391Skarels * 187230391Skarels ********/ 187330391Skarels 187430391Skarels blitc(unit, chr) 187530391Skarels int unit; 187630391Skarels char chr; 187730391Skarels { 187830391Skarels register struct adder *adder; 187930391Skarels register struct dga *dga; 188030391Skarels register int i; 188132012Smarc static short inescape[NQD]; 188230391Skarels 188330391Skarels short x; 188430391Skarels 188532012Smarc /* init stuff */ 188630391Skarels 188730391Skarels adder = (struct adder *) qdmap[unit].adder; 188830391Skarels dga = (struct dga *) qdmap[unit].dga; 188930391Skarels 189030391Skarels chr &= 0x7F; 189130391Skarels 189232012Smarc /* 189332012Smarc * Support cursor addressing so vi will work. 189432012Smarc * Decode for "\E=%.%." cursor motion description. 189532012Smarc * 189632012Smarc * If we've seen an escape, grab up to three more 189732012Smarc * characters, bailing out if necessary. 189832012Smarc */ 189932012Smarc if (inescape[unit]) { 190032012Smarc switch (inescape[unit]++) { 190132012Smarc case 1: 190232012Smarc if (chr != '=') { 190332012Smarc /* bogus escape sequence */ 190432012Smarc inescape[unit] = 0; 190532012Smarc blitc(unit, chr); 190632012Smarc } 190732012Smarc return(0); 190832012Smarc case 2: 190932012Smarc /* position row */ 191032012Smarc cursor[unit].y = CHAR_HEIGHT * chr; 191132012Smarc if (cursor[unit].y > 863 - CHAR_HEIGHT) 191232012Smarc cursor[unit].y = 863 - CHAR_HEIGHT; 191332012Smarc dga->y_cursor = TRANY(cursor[unit].y); 191432012Smarc return(0); 191532012Smarc case 3: 191632012Smarc /* position column */ 191732012Smarc cursor[unit].x = CHAR_WIDTH * chr; 191832012Smarc if (cursor[unit].x > 1024 - CHAR_WIDTH) 191932012Smarc cursor[unit].x = 1023 - CHAR_WIDTH; 192032012Smarc dga->x_cursor = TRANX(cursor[unit].x); 192132012Smarc inescape[unit] = 0; 192232012Smarc return(0); 192332012Smarc default: 192432012Smarc inescape[unit] = 0; 192532012Smarc blitc(unit, chr); 192632012Smarc } 192732012Smarc } 192832012Smarc 192932012Smarc 193030391Skarels switch (chr) { 193130391Skarels 193230391Skarels case '\r': /* return char */ 193330391Skarels cursor[unit].x = 0; 193430391Skarels dga->x_cursor = TRANX(cursor[unit].x); 193530391Skarels return(0); 193630391Skarels 193730391Skarels case '\t': /* tab char */ 193830391Skarels 193930391Skarels for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) { 194030391Skarels blitc(unit, ' '); 194130391Skarels } 194230391Skarels return(0); 194330391Skarels 194430391Skarels case '\n': /* line feed char */ 194530391Skarels 194630391Skarels if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { 194730391Skarels if (qdflags[unit].inuse & GRAPHIC_DEV) { 194830391Skarels cursor[unit].y = 0; 194930391Skarels } else { 195030391Skarels cursor[unit].y -= CHAR_HEIGHT; 195130391Skarels scroll_up(adder); 195230391Skarels } 195330391Skarels } 195430391Skarels dga->y_cursor = TRANY(cursor[unit].y); 195530391Skarels return(0); 195630391Skarels 195730391Skarels case '\b': /* backspace char */ 195830391Skarels if (cursor[unit].x > 0) { 195930391Skarels cursor[unit].x -= CHAR_WIDTH; 196030391Skarels dga->x_cursor = TRANX(cursor[unit].x); 196130391Skarels } 196230391Skarels return(0); 196330391Skarels 1964*34511Smarc case CTRL('k'): /* cursor up */ 196532012Smarc if (cursor[unit].y > 0) { 196632012Smarc cursor[unit].y -= CHAR_HEIGHT; 196732012Smarc dga->y_cursor = TRANY(cursor[unit].y); 196832012Smarc } 196932012Smarc return(0); 197032012Smarc 1971*34511Smarc case CTRL('^'): /* home cursor */ 197232012Smarc cursor[unit].x = 0; 197332012Smarc dga->x_cursor = TRANX(cursor[unit].x); 197432012Smarc cursor[unit].y = 0; 197532012Smarc dga->y_cursor = TRANY(cursor[unit].y); 197632012Smarc return(0); 197732012Smarc 1978*34511Smarc case CTRL('l'): /* cursor right */ 197932012Smarc if (cursor[unit].x < 1023 - CHAR_WIDTH) { 198032012Smarc cursor[unit].x += CHAR_WIDTH; 198132012Smarc dga->x_cursor = TRANX(cursor[unit].x); 198232012Smarc } 198332012Smarc return(0); 198432012Smarc 1985*34511Smarc case CTRL('z'): /* clear screen */ 198632012Smarc setup_dragon(unit); 198732012Smarc clear_qd_screen(unit); 198832012Smarc /* and home cursor - termcap seems to assume this */ 198932012Smarc cursor[unit].x = 0; 199032012Smarc dga->x_cursor = TRANX(cursor[unit].x); 199132012Smarc cursor[unit].y = 0; 199232012Smarc dga->y_cursor = TRANY(cursor[unit].y); 199332012Smarc return(0); 199432012Smarc 199532012Smarc case '\033': /* start escape sequence */ 199632012Smarc inescape[unit] = 1; 199732012Smarc return(0); 199832012Smarc 199930391Skarels default: 200030391Skarels if (chr < ' ' || chr > '~') 200130391Skarels return(0); 200230391Skarels } 200330391Skarels 200432012Smarc /* setup VIPER operand control registers */ 200530391Skarels 200630391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ 200730391Skarels write_ID(adder, SRC1_OCR_B, 200830391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 200930391Skarels 201030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ 201130391Skarels write_ID(adder, SRC1_OCR_B, 201230391Skarels EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); 201330391Skarels 201430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 201530391Skarels write_ID(adder, DST_OCR_B, 201630391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 201730391Skarels 201830391Skarels write_ID(adder, MASK_1, 0xFFFF); 201930391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); 202030391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 202130391Skarels 202232012Smarc /* load DESTINATION origin and vectors */ 202330391Skarels 202430391Skarels adder->fast_dest_dy = 0; 202530391Skarels adder->slow_dest_dx = 0; 202630391Skarels adder->error_1 = 0; 202730391Skarels adder->error_2 = 0; 202830391Skarels 202930391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 203030391Skarels 203130391Skarels wait_status(adder, RASTEROP_COMPLETE); 203230391Skarels 203330391Skarels adder->destination_x = cursor[unit].x; 203430391Skarels adder->fast_dest_dx = CHAR_WIDTH; 203530391Skarels 203630391Skarels adder->destination_y = cursor[unit].y; 203730391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 203830391Skarels 203932012Smarc /* load SOURCE origin and vectors */ 204030391Skarels 204130391Skarels adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH); 204230391Skarels adder->source_1_y = FONT_Y; 204330391Skarels 204430391Skarels adder->source_1_dx = CHAR_WIDTH; 204530391Skarels adder->source_1_dy = CHAR_HEIGHT; 204630391Skarels 204730391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 204830391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 204930391Skarels 205032012Smarc /* update console cursor coordinates */ 205130391Skarels 205230391Skarels cursor[unit].x += CHAR_WIDTH; 205330391Skarels dga->x_cursor = TRANX(cursor[unit].x); 205430391Skarels 205532012Smarc /* auto-wrap margin */ 205630391Skarels if (cursor[unit].x > (1024 - CHAR_WIDTH)) { 205730391Skarels blitc(unit, '\r'); 205830391Skarels blitc(unit, '\n'); 205930391Skarels } 206030391Skarels 206130391Skarels } /* blitc */ 206230391Skarels 206330391Skarels qdreset(){} 206430391Skarels qd_init(){} 206530391Skarels 206630391Skarels /****************************************************************** 206730391Skarels * 206830391Skarels * INTERRUPT SERVICE ROUTINES START HERE: 206930391Skarels * 207030391Skarels ******************************************************************/ 207130391Skarels 207230391Skarels /***************************************************************** 207330391Skarels * 207430391Skarels * qddint()... service "DMA DONE" interrupt condition 207530391Skarels * 207630391Skarels *****************************************************************/ 207730391Skarels 207830391Skarels qddint(qd) 207930391Skarels int qd; 208030391Skarels { 208130391Skarels register struct DMAreq_header *header; 208230391Skarels register struct DMAreq *request; 208330391Skarels register struct dga *dga; 208430391Skarels struct adder *adder; 208530391Skarels 208630391Skarels int cookie; /* DMA adrs for QDSS */ 208730391Skarels int i; 208830391Skarels 208930391Skarels spl4(); /* allow interval timer in */ 209030391Skarels 209132012Smarc /* 209232012Smarc * init pointers 209332012Smarc */ 209430391Skarels 209530391Skarels header = DMAheader[qd]; /* register for optimization */ 209630391Skarels dga = (struct dga *) qdmap[qd].dga; 209730391Skarels adder = (struct adder *) qdmap[qd].adder; 209830391Skarels 209932012Smarc /* 210032012Smarc * if this interrupt flagged as bogus for interrupt flushing purposes.. 210132012Smarc */ 210230391Skarels 210330391Skarels if (DMA_ISIGNORE(header)) { 210430391Skarels DMA_CLRIGNORE(header); 210530391Skarels return; 210630391Skarels } 210730391Skarels 210830391Skarels /*---------------------------------------------------- 210930391Skarels * dump a DMA hardware error message if appropriate */ 211030391Skarels 211130391Skarels if (dga->csr & DMA_ERR) { 211230391Skarels 211330391Skarels if (dga->csr & PARITY_ERR) 2114*34511Smarc printf("qd%d: qddint: DMA hardware parity fault.\n", qd); 211530391Skarels 211630391Skarels if (dga->csr & BUS_ERR) 2117*34511Smarc printf("qd%d: qddint: DMA hardware bus error.\n", qd); 211830391Skarels } 211930391Skarels 212030391Skarels /*---------------------------------------- 212130391Skarels * if this was a DMA from user space... */ 212230391Skarels 212330391Skarels if (qdflags[qd].user_dma) { 212430391Skarels qdflags[qd].user_dma = 0; 212530391Skarels wakeup((caddr_t)&qdflags[qd].user_dma); 212630391Skarels return; 212730391Skarels } 212830391Skarels 212930391Skarels /*------------------------------------------------------------------------ 213030391Skarels * if we're doing DMA request queue services, field the error condition */ 213130391Skarels 213230391Skarels if (dga->csr & DMA_ERR) { 213330391Skarels 213430391Skarels dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ 213530391Skarels dga->csr |= DMA_ERR; /* clear error condition */ 213630391Skarels adder->command = CANCEL; /* cancel adder activity */ 213730391Skarels 213830391Skarels DMA_SETERROR(header); /* flag error in header status word */ 213930391Skarels DMA_CLRACTIVE(header); 214030391Skarels header->DMAreq[header->oldest].DMAdone |= HARD_ERROR; 214130391Skarels header->newest = header->oldest; 214230391Skarels header->used = 0; 214330391Skarels 214430391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 214530391Skarels selwakeup(rsel[qd], 0); 214630391Skarels rsel[qd] = 0; 214730391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 214830391Skarels } 214930391Skarels 215030391Skarels if (dga->bytcnt_lo != 0) { 215130391Skarels dga->bytcnt_lo = 0; 215230391Skarels dga->bytcnt_hi = 0; 215330391Skarels DMA_SETIGNORE(header); 215430391Skarels } 215530391Skarels 215630391Skarels return; 215730391Skarels } 215830391Skarels 215930391Skarels /*---------------------------------------------------------------------------- 216030391Skarels * if the DMA request queue is now becoming non-full, wakeup "select" client */ 216130391Skarels 216230391Skarels if (DMA_ISFULL(header)) { 216330391Skarels 216430391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 216530391Skarels selwakeup(rsel[qd], 0); 216630391Skarels rsel[qd] = 0; 216730391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 216830391Skarels } 216930391Skarels } 217030391Skarels 217130391Skarels header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE; 217230391Skarels 217330391Skarels if (DMA_ISEMPTY(header)) { 2174*34511Smarc printf("qd%d: qddint: unexpected interrupt\n", qd); 217530391Skarels return; 217630391Skarels } 217730391Skarels 217830391Skarels DMA_GETEND(header); /* update request queue indices */ 217930391Skarels 218030391Skarels /*------------------------------------------------------------ 218130391Skarels * if no more DMA pending, wake up "select" client and exit */ 218230391Skarels 218330391Skarels if (DMA_ISEMPTY(header)) { 218430391Skarels 218530391Skarels if (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) { 218630391Skarels selwakeup(rsel[qd], 0); 218730391Skarels rsel[qd] = 0; 218830391Skarels qdflags[qd].selmask &= ~SEL_WRITE; 218930391Skarels } 219030391Skarels 219130391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 219230391Skarels return; 219330391Skarels } 219430391Skarels 219530391Skarels /*--------------------------- 219630391Skarels * initiate next DMA xfer */ 219730391Skarels 219830391Skarels request = DMA_GETBEGIN(header); 219930391Skarels 220030391Skarels switch (request->DMAtype) { 220130391Skarels 220230391Skarels case DISPLIST: 220330391Skarels dga->csr |= DL_ENB; 220430391Skarels break; 220530391Skarels 220630391Skarels case PTOB: 220730391Skarels dga->csr |= PTOB_ENB; 220830391Skarels break; 220930391Skarels 221030391Skarels case BTOP: 221130391Skarels dga->csr |= BTOP_ENB; 221230391Skarels break; 221330391Skarels 221430391Skarels default: 2215*34511Smarc printf("qd%d: qddint: illegal DMAtype parameter.\n", qd); 221630391Skarels DMA_CLRACTIVE(header); /* flag DMA done */ 221730391Skarels return; 221830391Skarels } 221930391Skarels 222030391Skarels if (request->DMAdone & COUNT_ZERO) { 222130391Skarels dga->csr &= ~SET_DONE_FIFO; 222230391Skarels } else if (request->DMAdone & FIFO_EMPTY) { 222330391Skarels dga->csr |= SET_DONE_FIFO; 222430391Skarels } 222530391Skarels 222630391Skarels if (request->DMAdone & WORD_PACK) 222730391Skarels dga->csr &= ~BYTE_DMA; 222830391Skarels else if (request->DMAdone & BYTE_PACK) 222930391Skarels dga->csr |= BYTE_DMA; 223030391Skarels 223130391Skarels dga->csr |= DMA_IE; 223230391Skarels 223330391Skarels cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg; 223430391Skarels 223530391Skarels dga->adrs_lo = (short) cookie; 223630391Skarels dga->adrs_hi = (short) (cookie >> 16); 223730391Skarels 223830391Skarels dga->bytcnt_lo = (short) request->length; 223930391Skarels dga->bytcnt_hi = (short) (request->length >> 16); 224030391Skarels 224130391Skarels return; 224230391Skarels } 224330391Skarels 224430391Skarels /***************************************************************** 224530391Skarels * 224630391Skarels * qdaint()... ADDER interrupt service 224730391Skarels * 224830391Skarels *****************************************************************/ 224930391Skarels 225030391Skarels qdaint(qd) 225130391Skarels register int qd; 225230391Skarels { 225330391Skarels register struct adder *adder; 225430391Skarels struct color_buf *cbuf; 225530391Skarels 225630391Skarels short stat; 225730391Skarels int i; 225830391Skarels register struct rgb *rgbp; 225930391Skarels register short *red; 226030391Skarels register short *green; 226130391Skarels register short *blue; 226230391Skarels 226330391Skarels spl4(); /* allow interval timer in */ 226430391Skarels 226530391Skarels adder = (struct adder *) qdmap[qd].adder; 226630391Skarels 226730391Skarels /*------------------------------------------------------------------------ 226830391Skarels * service the vertical blank interrupt (VSYNC bit) by loading any pending 226930391Skarels * color map load request */ 227030391Skarels 227130391Skarels if (adder->status & VSYNC) { 227230391Skarels adder->status &= ~VSYNC; /* clear the interrupt */ 227330391Skarels 227430391Skarels cbuf = color_buf[qd]; 227530391Skarels if (cbuf->status & LOAD_COLOR_MAP) { 227630391Skarels 227730391Skarels red = (short *) qdmap[qd].red; 227830391Skarels green = (short *) qdmap[qd].green; 227930391Skarels blue = (short *) qdmap[qd].blue; 228030391Skarels 228130391Skarels for (i = cbuf->count, rgbp = cbuf->rgb; --i >= 0; rgbp++) { 228230391Skarels 228330391Skarels red[rgbp->offset] = (short) rgbp->red; 228430391Skarels green[rgbp->offset] = (short) rgbp->green; 228530391Skarels blue[rgbp->offset] = (short) rgbp->blue; 228630391Skarels } 228730391Skarels 228830391Skarels cbuf->status &= ~LOAD_COLOR_MAP; 228930391Skarels } 229030391Skarels } 229130391Skarels 229230391Skarels /*------------------------------------------------- 229330391Skarels * service the scroll interrupt (FRAME_SYNC bit) */ 229430391Skarels 229530391Skarels if (adder->status & FRAME_SYNC) { 229630391Skarels adder->status &= ~FRAME_SYNC; /* clear the interrupt */ 229730391Skarels 229830391Skarels if (scroll[qd]->status & LOAD_REGS) { 229930391Skarels 230030391Skarels for ( i = 1000, adder->status = 0 230130391Skarels ; i > 0 && !((stat = adder->status) & ID_SCROLL_READY) 230230391Skarels ; --i); 230330391Skarels 230430391Skarels if (i == 0) { 2305*34511Smarc printf("qd%d: qdaint: timeout on ID_SCROLL_READY\n", qd); 230630391Skarels return; 230730391Skarels } 230830391Skarels 230930391Skarels adder->ID_scroll_data = scroll[qd]->viper_constant; 231030391Skarels adder->ID_scroll_command = ID_LOAD | SCROLL_CONSTANT; 231130391Skarels 231230391Skarels adder->y_scroll_constant = scroll[qd]->y_scroll_constant; 231330391Skarels adder->y_offset_pending = scroll[qd]->y_offset; 231430391Skarels 231530391Skarels if (scroll[qd]->status & LOAD_INDEX) { 231630391Skarels 231730391Skarels adder->x_index_pending = scroll[qd]->x_index_pending; 231830391Skarels adder->y_index_pending = scroll[qd]->y_index_pending; 231930391Skarels } 232030391Skarels 232130391Skarels scroll[qd]->status = 0x00; 232230391Skarels } 232330391Skarels } 232430391Skarels } 232530391Skarels 232630391Skarels /***************************************************************** 232730391Skarels * 232830391Skarels * qdiint()... DUART input interrupt service routine 232930391Skarels * 233030391Skarels *****************************************************************/ 233130391Skarels 233230391Skarels qdiint(qd) 233330391Skarels register int qd; 233430391Skarels { 233530391Skarels register struct _vs_event *event; 233630391Skarels register struct qdinput *eqh; 233730391Skarels 233830391Skarels struct dga *dga; 233930391Skarels struct duart *duart; 234030391Skarels struct mouse_report *new_rep; 234130391Skarels 234230391Skarels struct uba_device *ui; 234330391Skarels struct tty *tp; 234430391Skarels 234530391Skarels char chr; 234630391Skarels int i,j; 234730391Skarels int k,l; 234830391Skarels 234930391Skarels u_short status; 235030391Skarels u_short data; 235130391Skarels u_short key; 235230391Skarels 235330391Skarels char do_wakeup = 0; /* flag to do a select wakeup call */ 235430391Skarels char a, b, c; /* mouse button test variables */ 235530391Skarels 235630391Skarels spl4(); /* allow interval timer in */ 235730391Skarels 235830391Skarels eqh = eq_header[qd]; /* optimized as a register */ 235930391Skarels new_rep = ¤t_rep[qd]; 236030391Skarels duart = (struct duart *) qdmap[qd].duart; 236130391Skarels 236230391Skarels /*----------------------------------------- 236330391Skarels * if the graphic device is turned on.. */ 236430391Skarels 236530391Skarels if (qdflags[qd].inuse & GRAPHIC_DEV) { 236630391Skarels 236730391Skarels /*--------------- 236830391Skarels * empty DUART */ 236930391Skarels 237030391Skarels while ((status = duart->statusA) & RCV_RDY || 237130391Skarels (status = duart->statusB) & RCV_RDY) { 237230391Skarels 237330391Skarels /*--------------------------------- 237430391Skarels * pick up LK-201 input (if any) */ 237530391Skarels 237630391Skarels if ((status = duart->statusA) & RCV_RDY) { 237730391Skarels 237830391Skarels /* if error condition, then reset it */ 237930391Skarels 238030391Skarels if ((status = duart->statusA) & 0x70) { 238130391Skarels duart->cmdA = 0x40; 238230391Skarels continue; 238330391Skarels } 238430391Skarels 238530391Skarels /* event queue full now? (overflow condition) */ 238630391Skarels 238730391Skarels if (ISFULL(eqh) == TRUE) { 2388*34511Smarc printf("qd%d: qdiint: event queue overflow\n", qd); 238930391Skarels break; 239030391Skarels } 239130391Skarels 239230391Skarels /*-------------------------------------- 239330391Skarels * Check for various keyboard errors */ 239430391Skarels 239530391Skarels key = duart->dataA & 0xFF; 239630391Skarels 239730391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 239830391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2399*34511Smarc printf("qd%d: qdiint: keyboard error, code = %x\n", 2400*34511Smarc qd, key); 240130391Skarels return(0); 240230391Skarels } 240330391Skarels 240430391Skarels if (key < LK_LOWEST) 240530391Skarels return(0); 240630391Skarels 240730391Skarels ++do_wakeup; /* request a select wakeup call */ 240830391Skarels 240930391Skarels event = PUTBEGIN(eqh); 241030391Skarels PUTEND(eqh); 241130391Skarels 241230391Skarels event->vse_key = key; 241330391Skarels event->vse_key &= 0x00FF; 241430391Skarels event->vse_x = eqh->curs_pos.x; 241530391Skarels event->vse_y = eqh->curs_pos.y; 241630391Skarels event->vse_time = TOY; 241730391Skarels event->vse_type = VSE_BUTTON; 241830391Skarels event->vse_direction = VSE_KBTRAW; 241930391Skarels event->vse_device = VSE_DKB; 242030391Skarels } 242130391Skarels 242230391Skarels /*------------------------------------- 242330391Skarels * pick up the mouse input (if any) */ 242430391Skarels 242530391Skarels if ((status = duart->statusB) & RCV_RDY && 242630391Skarels qdflags[qd].pntr_id == MOUSE_ID) { 242730391Skarels 242830391Skarels if (status & 0x70) { 242930391Skarels duart->cmdB = 0x40; 243030391Skarels continue; 243130391Skarels } 243230391Skarels 243330391Skarels /* event queue full now? (overflow condition) */ 243430391Skarels 243530391Skarels if (ISFULL(eqh) == TRUE) { 2436*34511Smarc printf("qd%d: qdiint: event queue overflow\n", qd); 243730391Skarels break; 243830391Skarels } 243930391Skarels 244030391Skarels data = duart->dataB; /* get report byte */ 244130391Skarels ++new_rep->bytcnt; /* bump report byte count */ 244230391Skarels 244330391Skarels /*--------------------------- 244430391Skarels * if 1st byte of report.. */ 244530391Skarels 244630391Skarels if ( data & START_FRAME) { 244730391Skarels new_rep->state = data; 244830391Skarels if (new_rep->bytcnt > 1) { 244930391Skarels new_rep->bytcnt = 1; /* start of new frame */ 245030391Skarels continue; /* ..continue looking */ 245130391Skarels } 245230391Skarels } 245330391Skarels 245430391Skarels /*--------------------------- 245530391Skarels * if 2nd byte of report.. */ 245630391Skarels 245730391Skarels else if (new_rep->bytcnt == 2) { 245830391Skarels new_rep->dx = data & 0x00FF; 245930391Skarels } 246030391Skarels 246130391Skarels /*------------------------------------------------- 246230391Skarels * if 3rd byte of report, load input event queue */ 246330391Skarels 246430391Skarels else if (new_rep->bytcnt == 3) { 246530391Skarels 246630391Skarels new_rep->dy = data & 0x00FF; 246730391Skarels new_rep->bytcnt = 0; 246830391Skarels 246930391Skarels /*----------------------------------- 247030391Skarels * if mouse position has changed.. */ 247130391Skarels 247230391Skarels if (new_rep->dx != 0 || new_rep->dy != 0) { 247330391Skarels 247430391Skarels /*--------------------------------------------- 247530391Skarels * calculate acceleration factor, if needed */ 247630391Skarels 247730391Skarels if (qdflags[qd].curs_acc > ACC_OFF) { 247830391Skarels 247930391Skarels if (qdflags[qd].curs_thr <= new_rep->dx) 248030391Skarels new_rep->dx += 248130391Skarels (new_rep->dx - qdflags[qd].curs_thr) 248230391Skarels * qdflags[qd].curs_acc; 248330391Skarels 248430391Skarels if (qdflags[qd].curs_thr <= new_rep->dy) 248530391Skarels new_rep->dy += 248630391Skarels (new_rep->dy - qdflags[qd].curs_thr) 248730391Skarels * qdflags[qd].curs_acc; 248830391Skarels } 248930391Skarels 249030391Skarels /*------------------------------------- 249130391Skarels * update cursor position coordinates */ 249230391Skarels 249330391Skarels if (new_rep->state & X_SIGN) { 249430391Skarels eqh->curs_pos.x += new_rep->dx; 249530391Skarels if (eqh->curs_pos.x > 1023) 249630391Skarels eqh->curs_pos.x = 1023; 249730391Skarels } 249830391Skarels else { 249930391Skarels eqh->curs_pos.x -= new_rep->dx; 250030391Skarels if (eqh->curs_pos.x < -15) 250130391Skarels eqh->curs_pos.x = -15; 250230391Skarels } 250330391Skarels 250430391Skarels if (new_rep->state & Y_SIGN) { 250530391Skarels eqh->curs_pos.y -= new_rep->dy; 250630391Skarels if (eqh->curs_pos.y < -15) 250730391Skarels eqh->curs_pos.y = -15; 250830391Skarels } 250930391Skarels else { 251030391Skarels eqh->curs_pos.y += new_rep->dy; 251130391Skarels if (eqh->curs_pos.y > 863) 251230391Skarels eqh->curs_pos.y = 863; 251330391Skarels } 251430391Skarels 251530391Skarels /*--------------------------------- 251630391Skarels * update cursor screen position */ 251730391Skarels 251830391Skarels dga = (struct dga *) qdmap[qd].dga; 251930391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 252030391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 252130391Skarels 252230391Skarels /*-------------------------------------------- 252330391Skarels * if cursor is in the box, no event report */ 252430391Skarels 252530391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 252630391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 252730391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 252830391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 252930391Skarels goto GET_MBUTTON; 253030391Skarels } 253130391Skarels 253230391Skarels /*--------------------------------- 253330391Skarels * report the mouse motion event */ 253430391Skarels 253530391Skarels event = PUTBEGIN(eqh); 253630391Skarels PUTEND(eqh); 253730391Skarels 253830391Skarels ++do_wakeup; /* request a select wakeup call */ 253930391Skarels 254030391Skarels event->vse_x = eqh->curs_pos.x; 254130391Skarels event->vse_y = eqh->curs_pos.y; 254230391Skarels 254330391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 254430391Skarels event->vse_type = VSE_MMOTION; /* pos changed */ 254530391Skarels event->vse_key = 0; 254630391Skarels event->vse_direction = 0; 254730391Skarels event->vse_time = TOY; /* time stamp */ 254830391Skarels } 254930391Skarels 255030391Skarels GET_MBUTTON: 255130391Skarels /*------------------------------- 255230391Skarels * if button state has changed */ 255330391Skarels 255430391Skarels a = new_rep->state & 0x07; /*mask nonbutton bits */ 255530391Skarels b = last_rep[qd].state & 0x07; 255630391Skarels 255730391Skarels if (a ^ b) { 255830391Skarels 255930391Skarels for ( c = 1; c < 8; c <<= 1) { 256030391Skarels 256130391Skarels if (!( c & (a ^ b))) /* this button change? */ 256230391Skarels continue; 256330391Skarels 256430391Skarels /* event queue full? (overflow condition) */ 256530391Skarels 256630391Skarels if (ISFULL(eqh) == TRUE) { 2567*34511Smarc printf("qd%d: qdiint: event queue overflow\n", qd); 256830391Skarels break; 256930391Skarels } 257030391Skarels 257130391Skarels event = PUTBEGIN(eqh); /* get new event */ 257230391Skarels PUTEND(eqh); 257330391Skarels 257430391Skarels ++do_wakeup; /* request select wakeup */ 257530391Skarels 257630391Skarels event->vse_x = eqh->curs_pos.x; 257730391Skarels event->vse_y = eqh->curs_pos.y; 257830391Skarels 257930391Skarels event->vse_device = VSE_MOUSE; /* mouse */ 258030391Skarels event->vse_type = VSE_BUTTON; /* new button */ 258130391Skarels event->vse_time = TOY; /* time stamp */ 258230391Skarels 258330391Skarels /* flag changed button and if up or down */ 258430391Skarels 258530391Skarels if (c == RIGHT_BUTTON) 258630391Skarels event->vse_key = VSE_RIGHT_BUTTON; 258730391Skarels else if (c == MIDDLE_BUTTON) 258830391Skarels event->vse_key = VSE_MIDDLE_BUTTON; 258930391Skarels else if (c == LEFT_BUTTON) 259030391Skarels event->vse_key = VSE_LEFT_BUTTON; 259130391Skarels 259230391Skarels /* set bit = button depressed */ 259330391Skarels 259430391Skarels if (c & a) 259530391Skarels event->vse_direction = VSE_KBTDOWN; 259630391Skarels else 259730391Skarels event->vse_direction = VSE_KBTUP; 259830391Skarels } 259930391Skarels } 260030391Skarels 260130391Skarels /* refresh last report */ 260230391Skarels 260330391Skarels last_rep[qd] = current_rep[qd]; 260430391Skarels 260530391Skarels } /* get last byte of report */ 260630391Skarels } /* pickup mouse input */ 260730391Skarels 260830391Skarels /*-------------------------------- 260930391Skarels * pickup tablet input, if any */ 261030391Skarels 261130391Skarels else if ((status = duart->statusB) & RCV_RDY && 261230391Skarels qdflags[qd].pntr_id == TABLET_ID) { 261330391Skarels 261430391Skarels if (status & 0x70) { 261530391Skarels duart->cmdB = 0x40; 261630391Skarels continue; 261730391Skarels } 261830391Skarels 261930391Skarels /* event queue full now? (overflow condition) */ 262030391Skarels 262130391Skarels if (ISFULL(eqh) == TRUE) { 2622*34511Smarc printf("qd%d: qdiint: event queue overflow\n", qd); 262330391Skarels break; 262430391Skarels } 262530391Skarels 262630391Skarels data = duart->dataB; /* get report byte */ 262730391Skarels ++new_rep->bytcnt; /* bump report byte count */ 262830391Skarels 262930391Skarels /*--------------------------- 263030391Skarels * if 1st byte of report.. */ 263130391Skarels 263230391Skarels if (data & START_FRAME) { 263330391Skarels new_rep->state = data; 263430391Skarels if (new_rep->bytcnt > 1) { 263530391Skarels new_rep->bytcnt = 1; /* start of new frame */ 263630391Skarels continue; /* ..continue looking */ 263730391Skarels } 263830391Skarels } 263930391Skarels 264030391Skarels /*--------------------------- 264130391Skarels * if 2nd byte of report.. */ 264230391Skarels 264330391Skarels else if (new_rep->bytcnt == 2) { 264430391Skarels new_rep->dx = data & 0x3F; 264530391Skarels } 264630391Skarels 264730391Skarels /*--------------------------- 264830391Skarels * if 3rd byte of report.. */ 264930391Skarels 265030391Skarels else if (new_rep->bytcnt == 3) { 265130391Skarels new_rep->dx |= (data & 0x3F) << 6; 265230391Skarels } 265330391Skarels 265430391Skarels /*--------------------------- 265530391Skarels * if 4th byte of report.. */ 265630391Skarels 265730391Skarels else if (new_rep->bytcnt == 4) { 265830391Skarels new_rep->dy = data & 0x3F; 265930391Skarels } 266030391Skarels 266130391Skarels /*------------------------------------------------- 266230391Skarels * if 5th byte of report, load input event queue */ 266330391Skarels 266430391Skarels else if (new_rep->bytcnt == 5) { 266530391Skarels 266630391Skarels new_rep->dy |= (data & 0x3F) << 6; 266730391Skarels new_rep->bytcnt = 0; 266830391Skarels 266930391Skarels /*------------------------------------- 267030391Skarels * update cursor position coordinates */ 267130391Skarels 267230391Skarels new_rep->dx /= qdflags[qd].tab_res; 267330391Skarels new_rep->dy = (2200 - new_rep->dy) 267430391Skarels / qdflags[qd].tab_res; 267530391Skarels 267630391Skarels if (new_rep->dx > 1023) { 267730391Skarels new_rep->dx = 1023; 267830391Skarels } 267930391Skarels if (new_rep->dy > 863) { 268030391Skarels new_rep->dy = 863; 268130391Skarels } 268230391Skarels 268330391Skarels /* 268430391Skarels * report an event if the puck/stylus has moved 268530391Skarels */ 268630391Skarels 268730391Skarels if (eqh->curs_pos.x != new_rep->dx || 268830391Skarels eqh->curs_pos.y != new_rep->dy) { 268930391Skarels 269030391Skarels eqh->curs_pos.x = new_rep->dx; 269130391Skarels eqh->curs_pos.y = new_rep->dy; 269230391Skarels 269330391Skarels /*--------------------------------- 269430391Skarels * update cursor screen position */ 269530391Skarels 269630391Skarels dga = (struct dga *) qdmap[qd].dga; 269730391Skarels dga->x_cursor = TRANX(eqh->curs_pos.x); 269830391Skarels dga->y_cursor = TRANY(eqh->curs_pos.y); 269930391Skarels 270030391Skarels /* 270130391Skarels * if cursor is in the box, no event report 270230391Skarels */ 270330391Skarels 270430391Skarels if (eqh->curs_pos.x <= eqh->curs_box.right && 270530391Skarels eqh->curs_pos.x >= eqh->curs_box.left && 270630391Skarels eqh->curs_pos.y >= eqh->curs_box.top && 270730391Skarels eqh->curs_pos.y <= eqh->curs_box.bottom ) { 270830391Skarels goto GET_TBUTTON; 270930391Skarels } 271030391Skarels 271130391Skarels /*--------------------------------- 271230391Skarels * report the tablet motion event */ 271330391Skarels 271430391Skarels event = PUTBEGIN(eqh); 271530391Skarels PUTEND(eqh); 271630391Skarels 271730391Skarels ++do_wakeup; /* request a select wakeup call */ 271830391Skarels 271930391Skarels event->vse_x = eqh->curs_pos.x; 272030391Skarels event->vse_y = eqh->curs_pos.y; 272130391Skarels 272230391Skarels event->vse_device = VSE_TABLET; /* tablet */ 272330391Skarels /* 272430391Skarels * right now, X handles tablet motion the same 272530391Skarels * as mouse motion 272630391Skarels */ 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 GET_TBUTTON: 273330391Skarels /*------------------------------- 273430391Skarels * if button state has changed */ 273530391Skarels 273630391Skarels a = new_rep->state & 0x1E; /* mask nonbutton bits */ 273730391Skarels b = last_rep[qd].state & 0x1E; 273830391Skarels 273930391Skarels if (a ^ b) { 274030391Skarels 274130391Skarels /* event queue full now? (overflow condition) */ 274230391Skarels 274330391Skarels if (ISFULL(eqh) == TRUE) { 2744*34511Smarc printf("qd%d: qdiint: event queue overflow\n", 2745*34511Smarc qd); 274630391Skarels break; 274730391Skarels } 274830391Skarels 274930391Skarels event = PUTBEGIN(eqh); /* get new event */ 275030391Skarels PUTEND(eqh); 275130391Skarels 275230391Skarels ++do_wakeup; /* request a select wakeup call */ 275330391Skarels 275430391Skarels event->vse_x = eqh->curs_pos.x; 275530391Skarels event->vse_y = eqh->curs_pos.y; 275630391Skarels 275730391Skarels event->vse_device = VSE_TABLET; /* tablet */ 275830391Skarels event->vse_type = VSE_BUTTON; /* button changed */ 275930391Skarels event->vse_time = TOY; /* time stamp */ 276030391Skarels 276130391Skarels /* define the changed button and if up or down */ 276230391Skarels 276330391Skarels for ( c = 1; c <= 0x10; c <<= 1) { 276430391Skarels if (c & (a ^ b)) { 276530391Skarels if (c == T_LEFT_BUTTON) 276630391Skarels event->vse_key = VSE_T_LEFT_BUTTON; 276730391Skarels else if (c == T_FRONT_BUTTON) 276830391Skarels event->vse_key = VSE_T_FRONT_BUTTON; 276930391Skarels else if (c == T_RIGHT_BUTTON) 277030391Skarels event->vse_key = VSE_T_RIGHT_BUTTON; 277130391Skarels else if (c == T_BACK_BUTTON) 277230391Skarels event->vse_key = VSE_T_BACK_BUTTON; 277330391Skarels break; 277430391Skarels } 277530391Skarels } 277630391Skarels 277730391Skarels /* set bit = button depressed */ 277830391Skarels 277930391Skarels if (c & a) 278030391Skarels event->vse_direction = VSE_KBTDOWN; 278130391Skarels else 278230391Skarels event->vse_direction = VSE_KBTUP; 278330391Skarels } 278430391Skarels 278530391Skarels /* refresh last report */ 278630391Skarels 278730391Skarels last_rep[qd] = current_rep[qd]; 278830391Skarels 278930391Skarels } /* get last byte of report */ 279030391Skarels } /* pick up tablet input */ 279130391Skarels 279230391Skarels } /* while input available.. */ 279330391Skarels 279430391Skarels /*--------------------- 279530391Skarels * do select wakeup */ 279630391Skarels 279730391Skarels if (rsel[qd] && do_wakeup && qdflags[qd].selmask & SEL_READ) { 279830391Skarels selwakeup(rsel[qd], 0); 279930391Skarels rsel[qd] = 0; 280030391Skarels qdflags[qd].selmask &= ~SEL_READ; 280130391Skarels do_wakeup = 0; 280230391Skarels } 280330391Skarels } 280430391Skarels 2805*34511Smarc /*----------------------------------------------------------------- 2806*34511Smarc * if the graphic device is not turned on, this is console input */ 280730391Skarels 280830391Skarels else { 280930391Skarels 281030391Skarels ui = qdinfo[qd]; 281130391Skarels if (ui == 0 || ui->ui_alive == 0) 281230391Skarels return(0); 281330391Skarels 281430391Skarels tp = &qd_tty[qd << 2]; 281530391Skarels 281630391Skarels /*-------------------------------------- 281730391Skarels * Get a character from the keyboard. */ 281830391Skarels 281930391Skarels while ((status = duart->statusA) & RCV_RDY) { 282030391Skarels 282130391Skarels key = duart->dataA; 282230391Skarels key &= 0xFF; 282330391Skarels 282430391Skarels /*-------------------------------------- 282530391Skarels * Check for various keyboard errors */ 282630391Skarels 282730391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 282830391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 2829*34511Smarc printf("qd%d: qdiint: Keyboard error, code = %x\n", 2830*34511Smarc qd, key); 283130391Skarels return(0); 283230391Skarels } 283330391Skarels 283430391Skarels if (key < LK_LOWEST) 283530391Skarels return(0); 283630391Skarels 283730391Skarels /*--------------------------------- 283830391Skarels * See if its a state change key */ 283930391Skarels 284030391Skarels switch (key) { 284130391Skarels 284230391Skarels case LOCK: 284330391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 284430391Skarels if (q_keyboard.lock) 284530391Skarels led_control(qd, LK_LED_ENABLE, LK_LED_LOCK); 284630391Skarels else 284730391Skarels led_control(qd, LK_LED_DISABLE, LK_LED_LOCK); 284830391Skarels return; 284930391Skarels 285030391Skarels case SHIFT: 285130391Skarels q_keyboard.shift ^= 0xFFFF; 285230391Skarels return; 285330391Skarels 285430391Skarels case CNTRL: 285530391Skarels q_keyboard.cntrl ^= 0xFFFF; 285630391Skarels return; 285730391Skarels 285830391Skarels case ALLUP: 285930391Skarels q_keyboard.cntrl = 0; 286030391Skarels q_keyboard.shift = 0; 286130391Skarels return; 286230391Skarels 286330391Skarels case REPEAT: 286430391Skarels chr = q_keyboard.last; 286530391Skarels break; 286630391Skarels 286730391Skarels /*------------------------------------------------------- 286830391Skarels * Test for cntrl characters. If set, see if the character 286930391Skarels * is elligible to become a control character. */ 287030391Skarels 287130391Skarels default: 287230391Skarels 287330391Skarels if (q_keyboard.cntrl) { 287430391Skarels chr = q_key[key]; 287530391Skarels if (chr >= ' ' && chr <= '~') 287630391Skarels chr &= 0x1F; 287730391Skarels } 287830391Skarels else if( q_keyboard.lock || q_keyboard.shift ) 287930391Skarels chr = q_shift_key[key]; 288030391Skarels else 288130391Skarels chr = q_key[key]; 288230391Skarels break; 288330391Skarels } 288430391Skarels 288530391Skarels q_keyboard.last = chr; 288630391Skarels 288730391Skarels /*----------------------------------- 288830391Skarels * Check for special function keys */ 288930391Skarels 289030391Skarels if (chr & 0x80) { 289130391Skarels char *string; 289230391Skarels string = q_special[chr & 0x7F]; 289330391Skarels while(*string) 289430391Skarels (*linesw[tp->t_line].l_rint)(*string++, tp); 289530391Skarels } 289630391Skarels else { 289730391Skarels (*linesw[tp->t_line].l_rint)(chr, tp); 289830391Skarels } 289930391Skarels } 290030391Skarels } 290130391Skarels 290230391Skarels return(0); 290330391Skarels 290430391Skarels } /* qdiint */ 290530391Skarels 290630391Skarels /****************************************************************** 290730391Skarels * 290830391Skarels * THE SUBROUTINES START HERE: 290930391Skarels * 291030391Skarels ******************************************************************/ 291130391Skarels 291230391Skarels /***************************************************************** 291330391Skarels * 291430391Skarels * clear_qd_screen()... clear the QDSS screen 291530391Skarels * 291630391Skarels ****************************************************************** 291730391Skarels * 291830391Skarels * >>> NOTE <<< 291930391Skarels * 292030391Skarels * This code requires that certain adder initialization be valid. To 292130391Skarels * assure that this requirement is satisfied, this routine should be 292230391Skarels * called only after calling the "setup_dragon()" function. 292330391Skarels * 292430391Skarels * Clear the bitmap a piece at a time. Since the fast scroll clear 292530391Skarels * only clears the current displayed portion of the bitmap put a 292630391Skarels * temporary value in the y limit register so we can access whole 292730391Skarels * bitmap 292830391Skarels * 292930391Skarels ****************/ 293030391Skarels 293130391Skarels clear_qd_screen(unit) 293230391Skarels int unit; 293330391Skarels { 293430391Skarels register struct adder *adder; 293530391Skarels adder = (struct adder *) qdmap[unit].adder; 293630391Skarels 293730391Skarels adder->x_limit = 1024; 293830391Skarels adder->y_limit = 2048 - CHAR_HEIGHT; 293930391Skarels adder->y_offset_pending = 0; 294030391Skarels 294130391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 294230391Skarels wait_status(adder, VSYNC); 294330391Skarels 294430391Skarels adder->y_scroll_constant = SCROLL_ERASE; 294530391Skarels 294630391Skarels wait_status(adder, VSYNC); 294730391Skarels wait_status(adder, VSYNC); 294830391Skarels 294930391Skarels adder->y_offset_pending = 864; 295030391Skarels 295130391Skarels wait_status(adder, VSYNC); 295230391Skarels wait_status(adder, VSYNC); 295330391Skarels 295430391Skarels adder->y_scroll_constant = SCROLL_ERASE; 295530391Skarels 295630391Skarels wait_status(adder, VSYNC); 295730391Skarels wait_status(adder, VSYNC); 295830391Skarels 295930391Skarels adder->y_offset_pending = 1728; 296030391Skarels 296130391Skarels wait_status(adder, VSYNC); 296230391Skarels wait_status(adder, VSYNC); 296330391Skarels 296430391Skarels adder->y_scroll_constant = SCROLL_ERASE; 296530391Skarels 296630391Skarels wait_status(adder, VSYNC); 296730391Skarels wait_status(adder, VSYNC); 296830391Skarels 296930391Skarels adder->y_offset_pending = 0; /* back to normal */ 297030391Skarels 297130391Skarels wait_status(adder, VSYNC); 297230391Skarels wait_status(adder, VSYNC); 297330391Skarels 297430391Skarels adder->x_limit = MAX_SCREEN_X; 297530391Skarels adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; 297630391Skarels 297730391Skarels } /* clear_qd_screen */ 297830391Skarels 297930391Skarels /********************************************************************** 298030391Skarels * 298130391Skarels * qdputc()... route kernel console output to display destination 298230391Skarels * 298330391Skarels *********************************************************************** 298430391Skarels * 298530391Skarels * calling convention: 298630391Skarels * 298730391Skarels * qdputc(chr); 298830391Skarels * 298930391Skarels * where: char chr; ;character for output 299030391Skarels * 299130391Skarels ****************/ 299230391Skarels 299330391Skarels qdputc(chr) 299430391Skarels register char chr; 299530391Skarels { 299630391Skarels 299732012Smarc /* if system is now physical, forget it (ie: crash DUMP) */ 299830391Skarels if ( (mfpr(MAPEN) & 1) == 0 ) 299930391Skarels return; 300030391Skarels 300132012Smarc blitc(0, chr & 0xff); 300232012Smarc if ((chr & 0177) == '\n') 300332012Smarc blitc(0, '\r'); 300430391Skarels 300530391Skarels 300630391Skarels } /* qdputc */ 300730391Skarels 300830391Skarels /******************************************************************* 300930391Skarels * 301030391Skarels * qdgetc()... get a character from the LK201 301130391Skarels * 301230391Skarels ******************************************************************* 301330391Skarels * 301430391Skarels * calling convention: 301530391Skarels * 301630391Skarels * qdgetc(); 301730391Skarels * 301830391Skarels * returns: the character read. 301930391Skarels * 302030391Skarels ****************/ 302130391Skarels 302230391Skarels qdgetc() 302330391Skarels { 302430391Skarels register short key; 302530391Skarels register char chr; 302630391Skarels register struct duart *duart; 302730391Skarels 302830391Skarels u_int status; 302930391Skarels 303030391Skarels duart = (struct duart *) qdmap[0].duart; 303130391Skarels 303230391Skarels /*-------------------------------------- 303330391Skarels * Get a character from the keyboard. */ 303430391Skarels 303530391Skarels LOOP: 303630391Skarels while (!((status = duart->statusA) & RCV_RDY)) 303730391Skarels ; 303830391Skarels 303930391Skarels key = duart->dataA; 304030391Skarels key &= 0xFF; 304130391Skarels 304230391Skarels /*-------------------------------------- 304330391Skarels * Check for various keyboard errors */ 304430391Skarels 304530391Skarels if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || 304630391Skarels key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { 304730391Skarels printf("Keyboard error, code = %x\n", key); 304830391Skarels return(0); 304930391Skarels } 305030391Skarels 305130391Skarels if (key < LK_LOWEST) 305230391Skarels return(0); 305330391Skarels 305430391Skarels /*--------------------------------- 305530391Skarels * See if its a state change key */ 305630391Skarels 305730391Skarels switch (key) { 305830391Skarels 305930391Skarels case LOCK: 306030391Skarels q_keyboard.lock ^= 0xffff; /* toggle */ 306130391Skarels if (q_keyboard.lock) 306230391Skarels led_control(LK_LED_ENABLE, LK_LED_LOCK); 306330391Skarels else 306430391Skarels led_control(LK_LED_DISABLE, LK_LED_LOCK); 306530391Skarels goto LOOP; 306630391Skarels 306730391Skarels case SHIFT: 306830391Skarels q_keyboard.shift ^= 0xFFFF; 306930391Skarels goto LOOP; 307030391Skarels 307130391Skarels case CNTRL: 307230391Skarels q_keyboard.cntrl ^= 0xFFFF; 307330391Skarels goto LOOP; 307430391Skarels 307530391Skarels case ALLUP: 307630391Skarels q_keyboard.cntrl = 0; 307730391Skarels q_keyboard.shift = 0; 307830391Skarels goto LOOP; 307930391Skarels 308030391Skarels case REPEAT: 308130391Skarels chr = q_keyboard.last; 308230391Skarels break; 308330391Skarels 308430391Skarels /*------------------------------------------------------- 308530391Skarels * Test for cntrl characters. If set, see if the character 308630391Skarels * is elligible to become a control character. */ 308730391Skarels 308830391Skarels default: 308930391Skarels 309030391Skarels if (q_keyboard.cntrl) { 309130391Skarels chr = q_key[key]; 309230391Skarels if (chr >= ' ' && chr <= '~') 309330391Skarels chr &= 0x1F; 309430391Skarels } 309530391Skarels else if ( q_keyboard.lock || q_keyboard.shift ) 309630391Skarels chr = q_shift_key[key]; 309730391Skarels else 309830391Skarels chr = q_key[key]; 309930391Skarels break; 310030391Skarels } 310130391Skarels 310230391Skarels if (chr < ' ' && chr > '~') /* if input is non-displayable */ 310330391Skarels return(0); /* ..then pitch it! */ 310430391Skarels 310530391Skarels q_keyboard.last = chr; 310630391Skarels 310730391Skarels /*----------------------------------- 310830391Skarels * Check for special function keys */ 310930391Skarels 311030391Skarels if (chr & 0x80) /* pitch the function keys */ 311130391Skarels return(0); 311230391Skarels else 311330391Skarels return(chr); 311430391Skarels 311530391Skarels } /* qdgetc */ 311630391Skarels 311730391Skarels /********************************************************************** 311830391Skarels * 311930391Skarels * ldcursor()... load the mouse cursor's template RAM bitmap 312030391Skarels * 312130391Skarels ********************************************************************* 312230391Skarels * 312330391Skarels * calling convention: 312430391Skarels * 312530391Skarels * ldcursor(unit, bitmap); 312630391Skarels * u_int unit; 312730391Skarels * short *bitmap; 312830391Skarels * 312930391Skarels ****************/ 313030391Skarels 313130391Skarels ldcursor(unit, bitmap) 313230391Skarels u_int unit; 313330391Skarels short *bitmap; 313430391Skarels { 313530391Skarels register struct dga *dga; 313630391Skarels register short *temp; 313730391Skarels register int i; 313830391Skarels 313930391Skarels int cursor; 314030391Skarels 314130391Skarels dga = (struct dga *) qdmap[unit].dga; 314230391Skarels temp = (short *) qdmap[unit].template; 314330391Skarels 314430391Skarels if (dga->csr & CURS_ENB) { /* if the cursor is enabled.. */ 314530391Skarels cursor = -1; /* ..note that.. */ 314630391Skarels dga->csr &= ~CURS_ENB; /* ..and shut it off */ 314730391Skarels } 314830391Skarels else { 314930391Skarels cursor = 0; 315030391Skarels } 315130391Skarels 315230391Skarels dga->csr &= ~CURS_ENB; /* shut off the cursor */ 315330391Skarels 315430391Skarels temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ 315530391Skarels /* ..of the 8k WORD template space */ 315630391Skarels for (i = 0; i < 32; ++i) 315730391Skarels *temp++ = *bitmap++; 315830391Skarels 315930391Skarels if (cursor) { /* if cursor was enabled.. */ 316030391Skarels dga->csr |= CURS_ENB; /* ..turn it back on */ 316130391Skarels } 316230391Skarels 316330391Skarels return(0); 316430391Skarels 316530391Skarels } /* ldcursor */ 316630391Skarels 316730391Skarels /********************************************************************** 316830391Skarels * 316930391Skarels * ldfont()... put the console font in the QDSS off-screen memory 317030391Skarels * 317130391Skarels *********************************************************************** 317230391Skarels * 317330391Skarels * calling convention: 317430391Skarels * 317530391Skarels * ldfont(unit); 317630391Skarels * u_int unit; ;QDSS unit number 317730391Skarels * 317830391Skarels ****************/ 317930391Skarels 318030391Skarels ldfont(unit) 318130391Skarels u_int unit; 318230391Skarels { 318330391Skarels register struct adder *adder; 318430391Skarels 318530391Skarels int i; /* scratch variables */ 318630391Skarels int j; 318730391Skarels int k; 318830391Skarels short packed; 318930391Skarels 319030391Skarels adder = (struct adder *) qdmap[unit].adder; 319130391Skarels 3192*34511Smarc /*------------------------------------------ 3193*34511Smarc * setup VIPER operand control registers */ 319430391Skarels 319530391Skarels write_ID(adder, MASK_1, 0xFFFF); 319630391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 319730391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 319830391Skarels 319930391Skarels write_ID(adder, SRC1_OCR_B, 320030391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 320130391Skarels write_ID(adder, SRC2_OCR_B, 320230391Skarels EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); 320330391Skarels write_ID(adder, DST_OCR_B, 320430391Skarels EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 320530391Skarels 320630391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 320730391Skarels 3208*34511Smarc /*-------------------------- 3209*34511Smarc * load destination data */ 321030391Skarels 321130391Skarels wait_status(adder, RASTEROP_COMPLETE); 321230391Skarels 321330391Skarels adder->destination_x = FONT_X; 321430391Skarels adder->destination_y = FONT_Y; 321530391Skarels adder->fast_dest_dx = FONT_WIDTH; 321630391Skarels adder->slow_dest_dy = CHAR_HEIGHT; 321730391Skarels 3218*34511Smarc /*--------------------------------------- 3219*34511Smarc * setup for processor to bitmap xfer */ 322030391Skarels 322130391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 322230391Skarels adder->cmd = PBT | OCRB | 2 | DTE | 2; 322330391Skarels 3224*34511Smarc /*----------------------------------------------- 3225*34511Smarc * iteratively do the processor to bitmap xfer */ 322630391Skarels 322730391Skarels for (i = 0; i < ROWS; ++i) { 322830391Skarels 322930391Skarels /* PTOB a scan line */ 323030391Skarels 323130391Skarels for (j = 0, k = i; j < 48; ++j) { 323230391Skarels 323330391Skarels /* PTOB one scan of a char cell */ 323430391Skarels 323530391Skarels packed = q_font[k]; 323630391Skarels k += ROWS; 323730391Skarels packed |= ((short)q_font[k] << 8); 323830391Skarels k += ROWS; 323930391Skarels 324030391Skarels wait_status(adder, TX_READY); 324130391Skarels adder->id_data = packed; 324230391Skarels } 324330391Skarels } 324430391Skarels 324530391Skarels } /* ldfont */ 324630391Skarels 324730391Skarels /********************************************************************* 324830391Skarels * 324930391Skarels * led_control()... twiddle LK-201 LED's 325030391Skarels * 325130391Skarels ********************************************************************** 325230391Skarels * 325330391Skarels * led_control(unit, cmd, led_mask); 325430391Skarels * u_int unit; QDSS number 325530391Skarels * int cmd; LED enable/disable command 325630391Skarels * int led_mask; which LED(s) to twiddle 325730391Skarels * 325830391Skarels *************/ 325930391Skarels 326030391Skarels led_control(unit, cmd, led_mask) 326130391Skarels u_int unit; 326230391Skarels int cmd; 326330391Skarels int led_mask; 326430391Skarels { 326530391Skarels register int i; 326630391Skarels register int status; 326730391Skarels register struct duart *duart; 326830391Skarels 326930391Skarels duart = (struct duart *) qdmap[unit].duart; 327030391Skarels 327130391Skarels for (i = 1000; i > 0; --i) { 327230391Skarels if ((status = duart->statusA) & XMT_RDY) { 327330391Skarels duart->dataA = cmd; 327430391Skarels break; 327530391Skarels } 327630391Skarels } 327730391Skarels 327830391Skarels for (i = 1000; i > 0; --i) { 327930391Skarels if ((status = duart->statusA) & XMT_RDY) { 328030391Skarels duart->dataA = led_mask; 328130391Skarels break; 328230391Skarels } 328330391Skarels } 328430391Skarels 328530391Skarels if (i == 0) 328630391Skarels return(BAD); 328730391Skarels 328830391Skarels return(GOOD); 328930391Skarels 329030391Skarels } /* led_control */ 329130391Skarels 329230391Skarels /******************************************************************* 329330391Skarels * 329430391Skarels * scroll_up()... move the screen up one character height 329530391Skarels * 329630391Skarels ******************************************************************** 329730391Skarels * 329830391Skarels * calling convention: 329930391Skarels * 330030391Skarels * scroll_up(adder); 330130391Skarels * struct adder *adder; ;address of adder 330230391Skarels * 330330391Skarels ********/ 330430391Skarels 330530391Skarels scroll_up(adder) 330630391Skarels register struct adder *adder; 330730391Skarels { 330830391Skarels 3309*34511Smarc /*------------------------------------------ 3310*34511Smarc * setup VIPER operand control registers */ 331130391Skarels 331230391Skarels wait_status(adder, ADDRESS_COMPLETE); 331330391Skarels 331430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ 331530391Skarels 331630391Skarels write_ID(adder, MASK_1, 0xFFFF); 331730391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 331830391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 331930391Skarels 332030391Skarels write_ID(adder, SRC1_OCR_B, 332130391Skarels EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); 332230391Skarels write_ID(adder, DST_OCR_B, 332330391Skarels EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); 332430391Skarels 3325*34511Smarc /*---------------------------------------- 3326*34511Smarc * load DESTINATION origin and vectors */ 332730391Skarels 332830391Skarels adder->fast_dest_dy = 0; 332930391Skarels adder->slow_dest_dx = 0; 333030391Skarels adder->error_1 = 0; 333130391Skarels adder->error_2 = 0; 333230391Skarels 333330391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; 333430391Skarels 333530391Skarels adder->destination_x = 0; 333630391Skarels adder->fast_dest_dx = 1024; 333730391Skarels 333830391Skarels adder->destination_y = 0; 333930391Skarels adder->slow_dest_dy = 864 - CHAR_HEIGHT; 334030391Skarels 3341*34511Smarc /*----------------------------------- 3342*34511Smarc * load SOURCE origin and vectors */ 334330391Skarels 334430391Skarels adder->source_1_x = 0; 334530391Skarels adder->source_1_dx = 1024; 334630391Skarels 334730391Skarels adder->source_1_y = 0 + CHAR_HEIGHT; 334830391Skarels adder->source_1_dy = 864 - CHAR_HEIGHT; 334930391Skarels 335030391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 335130391Skarels adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; 335230391Skarels 3353*34511Smarc /*-------------------------------------------- 3354*34511Smarc * do a rectangle clear of last screen line */ 335530391Skarels 335630391Skarels write_ID(adder, MASK_1, 0xffff); 335730391Skarels write_ID(adder, SOURCE, 0xffff); 335830391Skarels write_ID(adder,DST_OCR_B, 335930391Skarels (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); 336030391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); 336130391Skarels adder->error_1 = 0; 336230391Skarels adder->error_2 = 0; 336330391Skarels adder->slow_dest_dx = 0; /* set up the width of */ 336430391Skarels adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ 336530391Skarels 336630391Skarels adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; 336730391Skarels wait_status(adder, RASTEROP_COMPLETE); 336830391Skarels adder->destination_x = 0; 336930391Skarels adder->destination_y = 864 - CHAR_HEIGHT; 337030391Skarels 337130391Skarels adder->fast_dest_dx = 1024; /* set up the height */ 337230391Skarels adder->fast_dest_dy = 0; /* of rectangle */ 337330391Skarels 337430391Skarels write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); 337530391Skarels adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; 337630391Skarels 337730391Skarels } /* scroll_up */ 337830391Skarels 337930391Skarels /******************************************************************** 338030391Skarels * 338130391Skarels * init_shared()... init shared memory pointers and structures 338230391Skarels * 338330391Skarels ********************************************************************* 338430391Skarels * 338530391Skarels * calling convention: 338630391Skarels * 338730391Skarels * init_shared(unit); 338830391Skarels * u_int unit; 338930391Skarels * 339030391Skarels ****************/ 339130391Skarels 339230391Skarels init_shared(unit) 339330391Skarels register u_int unit; 339430391Skarels { 339530391Skarels register struct dga *dga; 339630391Skarels 339730391Skarels dga = (struct dga *) qdmap[unit].dga; 339830391Skarels 3399*34511Smarc /*-------------------------------------------------- 3400*34511Smarc * initialize the event queue pointers and header */ 340130391Skarels 340230391Skarels eq_header[unit] = (struct qdinput *) 340330391Skarels ((((int)event_shared & ~(0x01FF)) + 512) 340430391Skarels + (EVENT_BUFSIZE * unit)); 340530391Skarels 340630391Skarels eq_header[unit]->curs_pos.x = 0; 340730391Skarels eq_header[unit]->curs_pos.y = 0; 340830391Skarels 340930391Skarels dga->x_cursor = TRANX(eq_header[unit]->curs_pos.x); 341030391Skarels dga->y_cursor = TRANY(eq_header[unit]->curs_pos.y); 341130391Skarels 341230391Skarels eq_header[unit]->curs_box.left = 0; 341330391Skarels eq_header[unit]->curs_box.right = 0; 341430391Skarels eq_header[unit]->curs_box.top = 0; 341530391Skarels eq_header[unit]->curs_box.bottom = 0; 341630391Skarels 3417*34511Smarc /*--------------------------------------------------------- 3418*34511Smarc * assign a pointer to the DMA I/O buffer for this QDSS. */ 341930391Skarels 342030391Skarels DMAheader[unit] = (struct DMAreq_header *) 342130391Skarels (((int)(&DMA_shared[0] + 512) & ~0x1FF) 342230391Skarels + (DMAbuf_size * unit)); 342330391Skarels 342430391Skarels DMAheader[unit]->DMAreq = (struct DMAreq *) ((int)DMAheader[unit] 342530391Skarels + sizeof(struct DMAreq_header)); 342630391Skarels 342730391Skarels DMAheader[unit]->QBAreg = 0; 342830391Skarels DMAheader[unit]->status = 0; 342930391Skarels DMAheader[unit]->shared_size = DMAbuf_size; 343030391Skarels DMAheader[unit]->used = 0; 343130391Skarels DMAheader[unit]->size = 10; /* default = 10 requests */ 343230391Skarels DMAheader[unit]->oldest = 0; 343330391Skarels DMAheader[unit]->newest = 0; 343430391Skarels 3435*34511Smarc /*----------------------------------------------------------- 3436*34511Smarc * assign a pointer to the scroll structure for this QDSS. */ 343730391Skarels 343830391Skarels scroll[unit] = (struct scroll *) 343930391Skarels (((int)(&scroll_shared[0] + 512) & ~0x1FF) 344030391Skarels + (sizeof(struct scroll) * unit)); 344130391Skarels 344230391Skarels scroll[unit]->status = 0; 344330391Skarels scroll[unit]->viper_constant = 0; 344430391Skarels scroll[unit]->y_scroll_constant = 0; 344530391Skarels scroll[unit]->y_offset = 0; 344630391Skarels scroll[unit]->x_index_pending = 0; 344730391Skarels scroll[unit]->y_index_pending = 0; 344830391Skarels 3449*34511Smarc /*---------------------------------------------------------------- 3450*34511Smarc * assign a pointer to the color map write buffer for this QDSS */ 345130391Skarels 345230391Skarels color_buf[unit] = (struct color_buf *) 345330391Skarels (((int)(&color_shared[0] + 512) & ~0x1FF) 345430391Skarels + (COLOR_BUFSIZ * unit)); 345530391Skarels 345630391Skarels color_buf[unit]->status = 0; 345730391Skarels color_buf[unit]->count = 0; 345830391Skarels 345930391Skarels } /* init_shared */ 346030391Skarels 346130391Skarels /********************************************************************* 346230391Skarels * 346330391Skarels * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map 346430391Skarels * 346530391Skarels ********************************************************************** 346630391Skarels * 346730391Skarels * calling convention: 346830391Skarels * 346930391Skarels * setup_dragon(); 347030391Skarels * 347130391Skarels * return: NONE 347230391Skarels * 347330391Skarels ************************/ 347430391Skarels 347530391Skarels setup_dragon(unit) 347630391Skarels u_int unit; 347730391Skarels { 347830391Skarels 347930391Skarels register struct adder *adder; 348030391Skarels register struct dga *dga; 348130391Skarels short *memcsr; 348230391Skarels 348330391Skarels int i; /* general purpose variables */ 348430391Skarels int status; 348530391Skarels 348630391Skarels short top; /* clipping/scrolling boundaries */ 348730391Skarels short bottom; 348830391Skarels short right; 348930391Skarels short left; 349030391Skarels 349130391Skarels short *red; /* color map pointers */ 349230391Skarels short *green; 349330391Skarels short *blue; 349430391Skarels 3495*34511Smarc /*------------------ 3496*34511Smarc * init for setup */ 349730391Skarels 349830391Skarels adder = (struct adder *) qdmap[unit].adder; 349930391Skarels dga = (struct dga *) qdmap[unit].dga; 350030391Skarels memcsr = (short *) qdmap[unit].memcsr; 350130391Skarels 350230391Skarels dga->csr &= ~(DMA_IE | 0x700); /* halt DMA and kill the intrpts */ 350330391Skarels *memcsr = SYNC_ON; /* blank screen and turn off LED's */ 350430391Skarels adder->command = CANCEL; 350530391Skarels 3506*34511Smarc /*---------------------- 3507*34511Smarc * set monitor timing */ 350830391Skarels 350930391Skarels adder->x_scan_count_0 = 0x2800; 351030391Skarels adder->x_scan_count_1 = 0x1020; 351130391Skarels adder->x_scan_count_2 = 0x003A; 351230391Skarels adder->x_scan_count_3 = 0x38F0; 351330391Skarels adder->x_scan_count_4 = 0x6128; 351430391Skarels adder->x_scan_count_5 = 0x093A; 351530391Skarels adder->x_scan_count_6 = 0x313C; 351630391Skarels adder->sync_phase_adj = 0x0100; 351730391Skarels adder->x_scan_conf = 0x00C8; 351830391Skarels 3519*34511Smarc /*--------------------------------------------------------- 3520*34511Smarc * got a bug in secound pass ADDER! lets take care of it */ 352130391Skarels 352230391Skarels /* normally, just use the code in the following bug fix code, but to 352330391Skarels * make repeated demos look pretty, load the registers as if there was 352430391Skarels * no bug and then test to see if we are getting sync */ 352530391Skarels 352630391Skarels adder->y_scan_count_0 = 0x135F; 352730391Skarels adder->y_scan_count_1 = 0x3363; 352830391Skarels adder->y_scan_count_2 = 0x2366; 352930391Skarels adder->y_scan_count_3 = 0x0388; 353030391Skarels 353130391Skarels /* if no sync, do the bug fix code */ 353230391Skarels 353330391Skarels if (wait_status(adder, VSYNC) == BAD) { 353430391Skarels 353530391Skarels /* first load all Y scan registers with very short frame and 353630391Skarels * wait for scroll service. This guarantees at least one SYNC 353730391Skarels * to fix the pass 2 Adder initialization bug (synchronizes 353830391Skarels * XCINCH with DMSEEDH) */ 353930391Skarels 354030391Skarels adder->y_scan_count_0 = 0x01; 354130391Skarels adder->y_scan_count_1 = 0x01; 354230391Skarels adder->y_scan_count_2 = 0x01; 354330391Skarels adder->y_scan_count_3 = 0x01; 354430391Skarels 354530391Skarels wait_status(adder, VSYNC); /* delay at least 1 full frame time */ 354630391Skarels wait_status(adder, VSYNC); 354730391Skarels 354830391Skarels /* now load the REAL sync values (in reverse order just to 354930391Skarels * be safe. */ 355030391Skarels 355130391Skarels adder->y_scan_count_3 = 0x0388; 355230391Skarels adder->y_scan_count_2 = 0x2366; 355330391Skarels adder->y_scan_count_1 = 0x3363; 355430391Skarels adder->y_scan_count_0 = 0x135F; 355530391Skarels } 355630391Skarels 355730391Skarels *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ 355830391Skarels 3559*34511Smarc /*---------------------------- 3560*34511Smarc * zero the index registers */ 356130391Skarels 356230391Skarels adder->x_index_pending = 0; 356330391Skarels adder->y_index_pending = 0; 356430391Skarels adder->x_index_new = 0; 356530391Skarels adder->y_index_new = 0; 356630391Skarels adder->x_index_old = 0; 356730391Skarels adder->y_index_old = 0; 356830391Skarels 356930391Skarels adder->pause = 0; 357030391Skarels 3571*34511Smarc /*---------------------------------------- 3572*34511Smarc * set rasterop mode to normal pen down */ 357330391Skarels 357430391Skarels adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; 357530391Skarels 3576*34511Smarc /*-------------------------------------------------- 3577*34511Smarc * set the rasterop registers to a default values */ 357830391Skarels 357930391Skarels adder->source_1_dx = 1; 358030391Skarels adder->source_1_dy = 1; 358130391Skarels adder->source_1_x = 0; 358230391Skarels adder->source_1_y = 0; 358330391Skarels adder->destination_x = 0; 358430391Skarels adder->destination_y = 0; 358530391Skarels adder->fast_dest_dx = 1; 358630391Skarels adder->fast_dest_dy = 0; 358730391Skarels adder->slow_dest_dx = 0; 358830391Skarels adder->slow_dest_dy = 1; 358930391Skarels adder->error_1 = 0; 359030391Skarels adder->error_2 = 0; 359130391Skarels 3592*34511Smarc /*------------------------ 3593*34511Smarc * scale factor = unity */ 359430391Skarels 359530391Skarels adder->fast_scale = UNITY; 359630391Skarels adder->slow_scale = UNITY; 359730391Skarels 3598*34511Smarc /*------------------------------- 3599*34511Smarc * set the source 2 parameters */ 360030391Skarels 360130391Skarels adder->source_2_x = 0; 360230391Skarels adder->source_2_y = 0; 360330391Skarels adder->source_2_size = 0x0022; 360430391Skarels 3605*34511Smarc /*----------------------------------------------- 3606*34511Smarc * initialize plane addresses for eight vipers */ 360730391Skarels 360830391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0001); 360930391Skarels write_ID(adder, PLANE_ADDRESS, 0x0000); 361030391Skarels 361130391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0002); 361230391Skarels write_ID(adder, PLANE_ADDRESS, 0x0001); 361330391Skarels 361430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0004); 361530391Skarels write_ID(adder, PLANE_ADDRESS, 0x0002); 361630391Skarels 361730391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0008); 361830391Skarels write_ID(adder, PLANE_ADDRESS, 0x0003); 361930391Skarels 362030391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0010); 362130391Skarels write_ID(adder, PLANE_ADDRESS, 0x0004); 362230391Skarels 362330391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0020); 362430391Skarels write_ID(adder, PLANE_ADDRESS, 0x0005); 362530391Skarels 362630391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0040); 362730391Skarels write_ID(adder, PLANE_ADDRESS, 0x0006); 362830391Skarels 362930391Skarels write_ID(adder, CS_UPDATE_MASK, 0x0080); 363030391Skarels write_ID(adder, PLANE_ADDRESS, 0x0007); 363130391Skarels 363230391Skarels /* initialize the external registers. */ 363330391Skarels 363430391Skarels write_ID(adder, CS_UPDATE_MASK, 0x00FF); 363530391Skarels write_ID(adder, CS_SCROLL_MASK, 0x00FF); 363630391Skarels 363730391Skarels /* initialize resolution mode */ 363830391Skarels 363930391Skarels write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ 364030391Skarels write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ 364130391Skarels 364230391Skarels /* initialize viper registers */ 364330391Skarels 364430391Skarels write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); 364530391Skarels write_ID(adder, SCROLL_FILL, 0x0000); 364630391Skarels 3647*34511Smarc /*---------------------------------------------------- 3648*34511Smarc * set clipping and scrolling limits to full screen */ 364930391Skarels 365030391Skarels for ( i = 1000, adder->status = 0 365130391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 365230391Skarels ; --i); 365330391Skarels 365430391Skarels if (i == 0) 3655*34511Smarc printf("qd%d: setup_dragon: timeout on ADDRESS_COMPLETE\n", unit); 365630391Skarels 365730391Skarels top = 0; 365830391Skarels bottom = 2048; 365930391Skarels left = 0; 366030391Skarels right = 1024; 366130391Skarels 366230391Skarels adder->x_clip_min = left; 366330391Skarels adder->x_clip_max = right; 366430391Skarels adder->y_clip_min = top; 366530391Skarels adder->y_clip_max = bottom; 366630391Skarels 366730391Skarels adder->scroll_x_min = left; 366830391Skarels adder->scroll_x_max = right; 366930391Skarels adder->scroll_y_min = top; 367030391Skarels adder->scroll_y_max = bottom; 367130391Skarels 367230391Skarels wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ 367330391Skarels wait_status(adder, VSYNC); 367430391Skarels 367530391Skarels adder->x_index_pending = left; 367630391Skarels adder->y_index_pending = top; 367730391Skarels adder->x_index_new = left; 367830391Skarels adder->y_index_new = top; 367930391Skarels adder->x_index_old = left; 368030391Skarels adder->y_index_old = top; 368130391Skarels 368230391Skarels for ( i = 1000, adder->status = 0 368330391Skarels ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) 368430391Skarels ; --i); 368530391Skarels 368630391Skarels if (i == 0) 3687*34511Smarc printf("qd%d: setup_dragon: timeout on ADDRESS_COMPLETE\n", unit); 368830391Skarels 368930391Skarels write_ID(adder, LEFT_SCROLL_MASK, 0x0000); 369030391Skarels write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); 369130391Skarels 3692*34511Smarc /*------------------------------------------------------------ 3693*34511Smarc * set source and the mask register to all ones (ie: white) */ 369430391Skarels 369530391Skarels write_ID(adder, SOURCE, 0xFFFF); 369630391Skarels write_ID(adder, MASK_1, 0xFFFF); 369730391Skarels write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); 369830391Skarels write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); 369930391Skarels 3700*34511Smarc /*-------------------------------------------------------------- 3701*34511Smarc * initialize Operand Control Register banks for fill command */ 370230391Skarels 370330391Skarels write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); 370430391Skarels write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); 370530391Skarels write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 370630391Skarels 370730391Skarels write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); 370830391Skarels write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); 370930391Skarels write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); 371030391Skarels 3711*34511Smarc /*------------------------------------------------------------------ 3712*34511Smarc * init Logic Unit Function registers, (these are just common values, 371330391Skarels * and may be changed as required). */ 371430391Skarels 371530391Skarels write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); 371630391Skarels write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); 371730391Skarels write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); 371830391Skarels write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); 371930391Skarels 3720*34511Smarc /*---------------------------------------- 3721*34511Smarc * load the color map for black & white */ 372230391Skarels 372330391Skarels for ( i = 0, adder->status = 0 372430391Skarels ; i < 10000 && !((status = adder->status) & VSYNC) 372530391Skarels ; ++i); 372630391Skarels 372730391Skarels if (i == 0) 3728*34511Smarc printf("qd%d: setup_dragon: timeout on VSYNC\n", unit); 372930391Skarels 373030391Skarels red = (short *) qdmap[unit].red; 373130391Skarels green = (short *) qdmap[unit].green; 373230391Skarels blue = (short *) qdmap[unit].blue; 373330391Skarels 373430391Skarels *red++ = 0x00; /* black */ 373530391Skarels *green++ = 0x00; 373630391Skarels *blue++ = 0x00; 373730391Skarels 373830391Skarels *red-- = 0xFF; /* white */ 373930391Skarels *green-- = 0xFF; 374030391Skarels *blue-- = 0xFF; 374130391Skarels 374230391Skarels /*---------------------------------- 374330391Skarels * set color map for mouse cursor */ 374430391Skarels 374530391Skarels red += 254; 374630391Skarels green += 254; 374730391Skarels blue += 254; 374830391Skarels 374930391Skarels *red++ = 0x00; /* black */ 375030391Skarels *green++ = 0x00; 375130391Skarels *blue++ = 0x00; 375230391Skarels 375330391Skarels *red = 0xFF; /* white */ 375430391Skarels *green = 0xFF; 375530391Skarels *blue = 0xFF; 375630391Skarels 375730391Skarels return(0); 375830391Skarels 375930391Skarels } /* setup_dragon */ 376030391Skarels 376130391Skarels /****************************************************************** 376230391Skarels * 376330391Skarels * setup_input()... init the DUART and set defaults in input 376430391Skarels * devices 376530391Skarels * 376630391Skarels ******************************************************************* 376730391Skarels * 376830391Skarels * calling convention: 376930391Skarels * 377030391Skarels * setup_input(unit); 377130391Skarels * 377230391Skarels * where: unit - is the QDSS unit number to be setup 377330391Skarels * 377430391Skarels *********/ 377530391Skarels 377630391Skarels setup_input(unit) 377730391Skarels u_int unit; 377830391Skarels { 377930391Skarels register struct duart *duart; /* DUART register structure pointer */ 378030391Skarels register int i; /* scratch variable */ 378130391Skarels register int bits; 378230391Skarels 378330391Skarels char id_byte; 378430391Skarels short status; 378530391Skarels 3786*34511Smarc /*--------------- 3787*34511Smarc * init stuff */ 378830391Skarels 378930391Skarels duart = (struct duart *) qdmap[unit].duart; 379030391Skarels duart->imask = 0; 379130391Skarels 3792*34511Smarc /*--------------------------------------------- 3793*34511Smarc * setup the DUART for kbd & pointing device */ 379430391Skarels 379530391Skarels duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ 379630391Skarels duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ 379730391Skarels /* no RTS control,char error mode */ 379830391Skarels duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ 379930391Skarels /* no RTS control,no echo or loop */ 380030391Skarels duart->cmdB = RESET_M; /* reset mode reg pntr for host */ 380130391Skarels duart->modeB = 0x07; /* 8 bits, odd parity, rcv IE.. */ 380230391Skarels /* ..no RTS cntrl, char error mode */ 380330391Skarels duart->modeB = 0x07; /* 1 stop bit,CTS does not IE XMT */ 380430391Skarels /* no RTS control,no echo or loop */ 380530391Skarels 380630391Skarels duart->auxctl = 0x00; /* baud rate set 1 */ 380730391Skarels 380830391Skarels duart->clkselA = 0x99; /* 4800 baud for kbd */ 380930391Skarels duart->clkselB = 0x99; /* 4800 baud for mouse */ 381030391Skarels 381130391Skarels /* reset everything for keyboard */ 381230391Skarels 381330391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 381430391Skarels duart->cmdA = bits; 381530391Skarels 381630391Skarels /* reset everything for host */ 381730391Skarels 381830391Skarels for (bits = RESET_M; bits < START_BREAK; bits += 0x10) 381930391Skarels duart->cmdB = bits; 382030391Skarels 382130391Skarels duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ 382230391Skarels duart->cmdB = EN_RCV | EN_XMT; /* enbl xmt & rcv for pointer device */ 382330391Skarels 3824*34511Smarc /*-------------------------------------------- 3825*34511Smarc * init keyboard defaults (DUART channel A) */ 382630391Skarels 382730391Skarels for (i = 500; i > 0; --i) { 382830391Skarels if ((status = duart->statusA) & XMT_RDY) { 382930391Skarels duart->dataA = LK_DEFAULTS; 383030391Skarels break; 383130391Skarels } 383230391Skarels } 383330391Skarels 383430391Skarels for (i = 100000; i > 0; --i) { 383530391Skarels if ((status = duart->statusA) & RCV_RDY) { 383630391Skarels break; 383730391Skarels } 383830391Skarels } 383930391Skarels 384030391Skarels status = duart->dataA; /* flush the ACK */ 384130391Skarels 3842*34511Smarc /*-------------------------------- 3843*34511Smarc * identify the pointing device */ 384430391Skarels 384530391Skarels for (i = 500; i > 0; --i) { 384630391Skarels if ((status = duart->statusB) & XMT_RDY) { 384730391Skarels duart->dataB = SELF_TEST; 384830391Skarels break; 384930391Skarels } 385030391Skarels } 385130391Skarels 385230391Skarels /*----------------------------------------- 385330391Skarels * wait for 1st byte of self test report */ 385430391Skarels 385530391Skarels for (i = 100000; i > 0; --i) { 385630391Skarels if ((status = duart->statusB) & RCV_RDY) { 385730391Skarels break; 385830391Skarels } 385930391Skarels } 386030391Skarels 386130391Skarels if (i == 0) { 3862*34511Smarc printf("qd[%d]: setup_input: timeout on 1st byte of self test\n", 3863*34511Smarc unit); 386430391Skarels goto OUT; 386530391Skarels } 386630391Skarels 386730391Skarels status = duart->dataB; 386830391Skarels 386930391Skarels /*----------------------------------------- 387030391Skarels * wait for ID byte of self test report */ 387130391Skarels 387230391Skarels for (i = 100000; i > 0; --i) { 387330391Skarels if ((status = duart->statusB) & RCV_RDY) { 387430391Skarels break; 387530391Skarels } 387630391Skarels } 387730391Skarels 387830391Skarels if (i == 0) { 3879*34511Smarc printf("qd[%d]: setup_input: timeout on 2nd byte of self test\n", 3880*34511Smarc unit); 388130391Skarels goto OUT; 388230391Skarels } 388330391Skarels 388430391Skarels id_byte = duart->dataB; 388530391Skarels 388630391Skarels /*------------------------------------ 388730391Skarels * wait for other bytes to come in */ 388830391Skarels 388930391Skarels for (i = 100000; i > 0; --i) { 389030391Skarels if ((status = duart->statusB) & RCV_RDY) { 389130391Skarels status = duart->dataB; 389230391Skarels break; 389330391Skarels } 389430391Skarels } 389530391Skarels 389630391Skarels if (i == 0) { 3897*34511Smarc printf("qd[%d]: setup_input: timeout on 3rd byte of self test\n", 3898*34511Smarc unit); 389930391Skarels goto OUT; 390030391Skarels } 390130391Skarels 390230391Skarels for (i = 100000; i > 0; --i) { 390330391Skarels if ((status = duart->statusB) & RCV_RDY) { 390430391Skarels status = duart->dataB; 390530391Skarels break; 390630391Skarels } 390730391Skarels } 390830391Skarels 390930391Skarels if (i == 0) { 3910*34511Smarc printf("qd[%d]: setup_input: timeout on 4th byte of self test\n", 3911*34511Smarc unit); 391230391Skarels goto OUT; 391330391Skarels } 391430391Skarels 391530391Skarels /*---------------------------------------------- 391630391Skarels * flag pointing device type and set defaults */ 391730391Skarels 391830391Skarels for (i=100000; i>0; --i); 391930391Skarels 392030391Skarels if ((id_byte & 0x0F) != TABLET_ID) { 392130391Skarels 392230391Skarels qdflags[unit].pntr_id = MOUSE_ID; 392330391Skarels 392430391Skarels for (i = 500; i > 0; --i) { 392530391Skarels if ((status = duart->statusB) & XMT_RDY) { 392630391Skarels duart->dataB = INC_STREAM_MODE; 392730391Skarels break; 392830391Skarels } 392930391Skarels } 393030391Skarels } else { 393130391Skarels 393230391Skarels qdflags[unit].pntr_id = TABLET_ID; 393330391Skarels 393430391Skarels for (i = 500; i > 0; --i) { 393530391Skarels if ((status = duart->statusB) & XMT_RDY) { 393630391Skarels duart->dataB = T_STREAM; 393730391Skarels break; 393830391Skarels } 393930391Skarels } 394030391Skarels } 394130391Skarels 3942*34511Smarc /*-------- 3943*34511Smarc * exit */ 394430391Skarels 394530391Skarels OUT: 394630391Skarels duart->imask = qdflags[unit].duart_imask; 394730391Skarels return(0); 394830391Skarels 394930391Skarels } /* setup_input */ 395030391Skarels 395130391Skarels /********************************************************************** 395230391Skarels * 395330391Skarels * wait_status()... delay for at least one display frame time 395430391Skarels * 395530391Skarels *********************************************************************** 395630391Skarels * 395730391Skarels * calling convention: 395830391Skarels * 395930391Skarels * wait_status(adder, mask); 396030391Skarels * struct *adder adder; 396130391Skarels * int mask; 396230391Skarels * 396330391Skarels * return: BAD means that we timed out without ever seeing the 396430391Skarels * vertical sync status bit 396530391Skarels * GOOD otherwise 396630391Skarels * 396730391Skarels **************/ 396830391Skarels 396930391Skarels wait_status(adder, mask) 397030391Skarels register struct adder *adder; 397130391Skarels register int mask; 397230391Skarels { 397330391Skarels register short status; 397430391Skarels int i; 397530391Skarels 397630391Skarels for ( i = 10000, adder->status = 0 397730391Skarels ; i > 0 && !((status = adder->status) & mask) 397830391Skarels ; --i); 397930391Skarels 398030391Skarels if (i == 0) { 3981*34511Smarc printf("wait_status: timeout polling for 0x%x in adder->status\n", 3982*34511Smarc mask); 398330391Skarels return(BAD); 398430391Skarels } 398530391Skarels 398630391Skarels return(GOOD); 398730391Skarels 398830391Skarels } /* wait_status */ 398930391Skarels 399030391Skarels /********************************************************************** 399130391Skarels * 399230391Skarels * write_ID()... write out onto the ID bus 399330391Skarels * 399430391Skarels *********************************************************************** 399530391Skarels * 399630391Skarels * calling convention: 399730391Skarels * 399830391Skarels * struct *adder adder; ;pntr to ADDER structure 399930391Skarels * short adrs; ;VIPER address 400030391Skarels * short data; ;data to be written 400130391Skarels * write_ID(adder); 400230391Skarels * 400330391Skarels * return: BAD means that we timed out waiting for status bits 400430391Skarels * VIPER-access-specific status bits 400530391Skarels * GOOD otherwise 400630391Skarels * 400730391Skarels **************/ 400830391Skarels 400930391Skarels write_ID(adder, adrs, data) 401030391Skarels register struct adder *adder; 401130391Skarels register short adrs; 401230391Skarels register short data; 401330391Skarels { 401430391Skarels int i; 401530391Skarels short status; 401630391Skarels 4017*34511Smarc for ( i = 100000, adder->status = 0; 4018*34511Smarc i > 0 && !((status = adder->status) & ADDRESS_COMPLETE); --i) 4019*34511Smarc ; 402030391Skarels 402130391Skarels if (i == 0) 402230391Skarels goto ERR; 402330391Skarels 4024*34511Smarc for ( i = 100000, adder->status = 0; 4025*34511Smarc i > 0 && !((status = adder->status) & TX_READY); --i) 4026*34511Smarc ; 402730391Skarels 402830391Skarels if (i > 0) { 402930391Skarels adder->id_data = data; 403030391Skarels adder->command = ID_LOAD | adrs; 403130391Skarels return(GOOD); 403230391Skarels } 403330391Skarels 403430391Skarels ERR: 4035*34511Smarc printf("write_ID: timeout trying to write to VIPER\n"); 403630391Skarels return(BAD); 403730391Skarels 403830391Skarels } /* write_ID */ 4039*34511Smarc #endif 4040