📄 qd.c
字号:
/* allow user write to scroll area */ *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; mtpr(TBIA, 0); /* clr CPU translation buf */ scroll[unit]->status = 0; adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie |= FRAME_SYNC; adder->interrupt_enable = qdflags[unit].adder_ie; /* return scroll area address */ *(int *)datap = (int) scroll[unit]; break; /*------------------------------------------------------------- * unmap shared scroll param area and disable scroll intrpts */ case QD_UNMAPSCROLL: if (qdflags[unit].mapped & MAPSCR) { qdflags[unit].mapped &= ~MAPSCR; ptep = (int *) ((VTOP(scroll[unit]) * 4) + (mfpr(SBR) | 0x80000000)); /* re-protect 512 scroll param area */ *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; mtpr(TBIA, 0); /* smash CPU's translation buf */ adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie &= ~FRAME_SYNC; adder->interrupt_enable = qdflags[unit].adder_ie; } break; /*----------------------------------------------------------- * map shared color map write buf and turn on vsync intrpt */ case QD_MAPCOLOR: qdflags[unit].mapped |= MAPCOLOR; ptep = (int *) ((VTOP(color_buf[unit]) * 4) + (mfpr(SBR) | 0x80000000)); /* allow user write to color map write buffer */ *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; mtpr(TBIA, 0); /* clr CPU translation buf */ adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie |= VSYNC; adder->interrupt_enable = qdflags[unit].adder_ie; /* return color area address */ *(int *)datap = (int) color_buf[unit]; break; /*-------------------------------------------------------------- * unmap shared color map write buffer and kill VSYNC intrpts */ case QD_UNMAPCOLOR: if (qdflags[unit].mapped & MAPCOLOR) { qdflags[unit].mapped &= ~MAPCOLOR; ptep = (int *) ((VTOP(color_buf[unit]) * 4) + (mfpr(SBR) | 0x80000000)); /* re-protect color map write buffer */ *ptep++ = (*ptep & ~PG_PROT) | PG_KW | PG_V; *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; mtpr(TBIA, 0); /* smash CPU's translation buf */ adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie &= ~VSYNC; adder->interrupt_enable = qdflags[unit].adder_ie; } break; /*--------------------------------------------- * give user write access to the event queue */ case QD_MAPEVENT: qdflags[unit].mapped |= MAPEQ; ptep = (int *) ((VTOP(eq_header[unit]) * 4) + (mfpr(SBR) | 0x80000000)); /* allow user write to 1K event queue */ *ptep++ = (*ptep & ~PG_PROT) | PG_UW | PG_V; *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; mtpr(TBIA, 0); /* clr CPU translation buf */ /* return event queue address */ *(int *)datap = (int) eq_header[unit]; break; /*----------------------------------------------- * pass caller's programming commands to LK201 */ case QD_PRGKBD: duart = (struct duart *) qdmap[unit].duart; cmdbuf = (struct prgkbd *) datap; /* pnt to kbd cmd buf */ /*---------------- * send command */ for (i = 1000; i > 0; --i) { if ((status = duart->statusA) & XMT_RDY) { duart->dataA = cmdbuf->cmd; break; } } if (i == 0) { mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [1]", unit); break; } /*---------------- * send param1? */ if (cmdbuf->cmd & LAST_PARAM) break; for (i = 1000; i > 0; --i) { if ((status = duart->statusA) & XMT_RDY) { duart->dataA = cmdbuf->param1; break; } } if (i == 0) { mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [2]", unit); break; } /*---------------- * send param2? */ if (cmdbuf->param1 & LAST_PARAM) break; for (i = 1000; i > 0; --i) { if ((status = duart->statusA) & XMT_RDY) { duart->dataA = cmdbuf->param2; break; } } if (i == 0) { mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [3]", unit); break; } break; /*---------------------------------------------------- * pass caller's programming commands to the mouse */ case QD_PRGMOUSE: duart = (struct duart *) qdmap[unit].duart; for (i = 1000; i > 0; --i) { if ((status = duart->statusB) & XMT_RDY) { duart->dataB = *datap; break; } } if (i == 0) { mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [4]", unit); } break; /*---------------------------------------------- * get QDSS configuration word and return it */ case QD_RDCONFIG: *(short *)datap = qdflags[unit].config; break; /*-------------------------------------------------------------- * re-route kernel console messages to the alternate console */ case QD_KERN_LOOP: qdflags[unit].kernel_loop = -1; break; case QD_KERN_UNLOOP: qdflags[unit].kernel_loop = 0; break; /*---------------------- * program the tablet */ case QD_PRGTABLET: duart = (struct duart *) qdmap[unit].duart; for (i = 1000; i > 0; --i) { if ((status = duart->statusB) & XMT_RDY) { duart->dataB = *datap; break; } } if (i == 0) { mprintf("\nqd%d: qdioctl: timeout on XMT_RDY [5]", unit); } break; /*----------------------------------------------- * program the tablet report resolution factor */ case QD_PRGTABRES: qdflags[unit].tab_res = *(short *)datap; break; case DEVIOCGET: /* device status */ devget = (struct devget *)datap; bzero(devget,sizeof(struct devget)); devget->category = DEV_TERMINAL; devget->bus = DEV_QB; bcopy(DEV_VCB02,devget->interface, strlen(DEV_VCB02)); bcopy(DEV_VR290,devget->device, strlen(DEV_VR290)); /* terminal */ devget->adpt_num = ui->ui_adpt; /* which adapter*/ devget->nexus_num = ui->ui_nexus; /* which nexus */ devget->bus_num = ui->ui_ubanum; /* which QB */ devget->ctlr_num = unit; /* which interf.*/ devget->slave_num = unit; /* which line */ bcopy(ui->ui_driver->ud_dname, devget->dev_name, strlen(ui->ui_driver->ud_dname)); /* Ultrix "qd" */ devget->unit_num = unit; /* qd line? */ devget->soft_count = sc->sc_softcnt; /* soft er. cnt.*/ devget->hard_count = sc->sc_hardcnt; /* hard er cnt. */ devget->stat = sc->sc_flags; /* status */ devget->category_stat = sc->sc_category_flags; /* cat. stat. */ break; default: /*----------------------------- * service tty type ioctl's */ if (!(minor_dev & 0x02)) { tp = &qd_tty[minor_dev]; error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, datap, flags); if (error >= 0) { return(error); } error = ttioctl(tp, cmd, datap, flags); if (error >= 0) { return(error); } /* if error = -1 then ioctl does not exist */ if (u.u_procp->p_progenv == A_POSIX) return (EINVAL); return (ENOTTY); } break; }/*--------------------------------* clean up and get outta here */ return(0);} /* qdioctl *//************************************************************************ qdselect()... service select call for event queue input***********************************************************************/qdselect(dev, rw)dev_t dev;int rw;{ register int s; register int unit; register struct tty *tp; u_int minor_dev = minor(dev); s = spl5(); unit = minor_dev >> 2; switch (rw) { case FREAD: if ((minor_dev & 0x03) == 2) { /* * this is a graphics device, so check for events */ if(!(ISEMPTY(eq_header[unit]))) { splx(s); return(1); } rsel[unit] = u.u_procp; qdflags[unit].selmask |= SEL_READ; splx(s); return(0); } else { /* * this is a tty device */ tp = &qd_tty[minor_dev]; if (ttnread(tp)) return(1); tp->t_rsel = u.u_procp; splx(s); return(0); } case FWRITE: if ((minor(dev) & 0x03) == 2) { /* * this is a graphics device, so check for dma buffers */ if (DMA_ISEMPTY(DMAheader[unit])) { splx(s); return(1); } rsel[unit] = u.u_procp; qdflags[unit].selmask |= SEL_WRITE; splx(s); return(0); } else { /* * this is a tty device */ tp = &qd_tty[minor_dev]; if (tp->t_outq.c_cc <= TTLOWAT(tp)) return(1); tp->t_wsel = u.u_procp; splx(s); return(0); } }} /* qdselect() *//***************************************************************** qdwrite()... output to the QDSS screen as a TTY****************************************************************/extern qd_strategy();qdwrite(dev, uio)dev_t dev;struct uio *uio;{ register struct tty *tp; register int minor_dev; register int unit; minor_dev = minor(dev); unit = (minor_dev >> 2) & 0x07; /*------------------------------*/ /* graphic device ... DMA xfers */ if (((minor_dev & 3) == GRAPHIC) && (qdflags[unit].inuse & GRAPHIC_DEV)) { return (physio(qd_strategy, &qdbuf[unit], dev, B_WRITE, minphys, uio)); } /*------------------------------*/ /* console or alternate console */ else { tp = &qd_tty[minor_dev]; return ((*linesw[tp->t_line].l_write)(tp, uio)); }}/***************************************************************** qdread()... read from QDSS keyboard as a TTY****************************************************************/qdread(dev, uio)dev_t dev;struct uio *uio;{ register struct tty *tp; register int minor_dev; register int unit; minor_dev = minor(dev); unit = (minor_dev >> 2) & 0x07; /*------------------------------ * if this is the console... */ if ((minor_dev & 0x03) != 0x02 && qdflags[unit].inuse & CONS_DEV) { tp = &qd_tty[minor_dev]; return ((*linesw[tp->t_line].l_read)(tp, uio)); } /*------------------------------------------------ * else this must be a bitmap-to-processor xfer */ else if (qdflags[unit].inuse & GRAPHIC_DEV) { return (physio(qd_strategy, &qdbuf[unit], dev, B_READ, minphys, uio)); }}/***************************************************************** qd_strategy()... strategy routine to do DMA****************************************************************/qd_strategy(bp)register struct buf *bp;{ register struct dga *dga; register struct adder *adder; char *DMAbufp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -