📄 qd.c
字号:
s = spl5(); dga->x_cursor = TRANX(pos->x); dga->y_cursor = TRANY(pos->y); eq_header[unit]->curs_pos.x = pos->x; eq_header[unit]->curs_pos.y = pos->y; splx(s); break; case QD_PRGCURSOR: /* * set the cursor acceleration factor */ curs = (struct prg_cursor *) datap; s = spl5(); qdflags[unit].curs_acc = curs->acc_factor; qdflags[unit].curs_thr = curs->threshold; splx(s); break; case QD_MAPDEVICE: /* * enable 'user write' to device pages */ qdflags[unit].mapped |= MAPDEV; qd = (struct qdmap *) &qdmap[unit]; /* * enable user write to template RAM */ mapix = VTOP((int)qd->template) - VTOP(qvmem[0]); ptep = (int *)(QVmap[0] + mapix); for (i = 0; i < btop(TMPSIZE); i++, ptep++) *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* * enable user write to registers */ mapix = VTOP((int)qd->adder) - VTOP(qvmem[0]); ptep = (int *)(QVmap[0] + mapix); for (i = 0; i < btop(REGSIZE); i++, ptep++) *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* * enable user write to color maps */ mapix = VTOP((int)qd->red) - VTOP(qvmem[0]); ptep = (int *)(QVmap[0] + mapix); for (i = 0; i < btop(CLRSIZE); i++, ptep++) *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* * enable user write to DUART */ mapix = VTOP((int)qd->duart) - VTOP(qvmem[0]); ptep = (int *)(QVmap[0] + mapix); *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; /* duart page */ mtpr(TBIA, 0); /* invalidate translation buffer */ /* * stuff qdmap structure in return buffer */ bcopy((caddr_t)qd, datap, sizeof(struct qdmap)); break; case QD_MAPIOBUF: /* * do setup for DMA by user process * * set 'user write enable' bits for DMA buffer */ qdflags[unit].mapped |= MAPDMA; ptep = (int *) ((VTOP(DMAheader[unit]) * 4) + (mfpr(SBR) | 0x80000000)); for (i = 0; i < btop(DMAbuf_size); i++, ptep++) *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; mtpr(TBIA, 0); /* invalidate translation buffer */ /* * set up QBUS map registers for DMA */ DMAheader[unit]->QBAreg = uballoc(0, (caddr_t)DMAheader[unit], DMAbuf_size, 0); if (DMAheader[unit]->QBAreg == 0) printf("qd%d: qdioctl: QBA setup error\n", unit); Qbus_unmap[unit] = DMAheader[unit]->QBAreg; DMAheader[unit]->QBAreg &= 0x3FFFF; /* * return I/O buf adr */ *(int *)datap = (int) DMAheader[unit]; break; case QD_MAPSCROLL: /* * map the shared scroll param area and enable scroll interpts */ qdflags[unit].mapped |= MAPSCR; ptep = (int *) ((VTOP(scroll[unit]) * 4) + (mfpr(SBR) | 0x80000000)); /* * allow user write to scroll area */ *ptep = (*ptep & ~PG_PROT) | PG_UW | PG_V; mtpr(TBIA, 0); /* invalidate 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; *(int *)datap = (int) scroll[unit]; /* return scroll area */ break; case QD_UNMAPSCROLL: /* * unmap shared scroll param area and disable scroll intrpts */ 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; case QD_MAPCOLOR: /* * map shared color map write buf and turn on vsync intrpt */ 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 = (*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; case QD_UNMAPCOLOR: /* * unmap shared color map write buffer and kill VSYNC intrpts */ 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 = (*ptep & ~PG_PROT) | PG_KW | PG_V; mtpr(TBIA, 0); adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie &= ~VSYNC; adder->interrupt_enable = qdflags[unit].adder_ie; } break; case QD_MAPEVENT: /* * give user write access to the event queue */ 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 = (*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; case QD_PRGKBD: /* * pass caller's programming commands to LK201 */ duart = (struct duart *)qdmap[unit].duart; cmdbuf = (struct prgkbd *)datap; /* pnt to kbd cmd buf */ /* * send command */ for (i = 1000; i > 0; --i) { if (duart->statusA&XMT_RDY) { duart->dataA = cmdbuf->cmd; break; } } if (i == 0) { printf("qd%d: qdioctl: timeout on XMT_RDY [1]\n", unit); break; } /* * send param1? */ if (cmdbuf->cmd & LAST_PARAM) break; for (i = 1000; i > 0; --i) { if (duart->statusA&XMT_RDY) { duart->dataA = cmdbuf->param1; break; } } if (i == 0) { printf("qd%d: qdioctl: timeout on XMT_RDY [2]\n", unit); break; } /* * send param2? */ if (cmdbuf->param1 & LAST_PARAM) break; for (i = 1000; i > 0; --i) { if (duart->statusA&XMT_RDY) { duart->dataA = cmdbuf->param2; break; } } if (i == 0) { printf("qd%d: qdioctl: timeout on XMT_RDY [3]\n", unit); break; } break; case QD_PRGMOUSE: /* * pass caller's programming commands to the mouse */ duart = (struct duart *) qdmap[unit].duart; for (i = 1000; i > 0; --i) { if (duart->statusB&XMT_RDY) { duart->dataB = *datap; break; } } if (i == 0) { printf("qd%d: qdioctl: timeout on XMT_RDY [4]\n", unit); } break; case QD_RDCONFIG: /* * get QDSS configuration word and return it */ *(short *)datap = qdflags[unit].config; break; case QD_KERN_LOOP: case QD_KERN_UNLOOP: /* * vestige from ultrix. BSD uses TIOCCONS to redirect * kernel console output. */ break; case QD_PRGTABLET: /* * program the tablet */ duart = (struct duart *) qdmap[unit].duart; for (i = 1000; i > 0; --i) { if (duart->statusB&XMT_RDY) { duart->dataB = *datap; break; } } if (i == 0) { printf("qd%d: qdioctl: timeout on XMT_RDY [5]\n", unit); } break; case QD_PRGTABRES: /* * program the tablet report resolution factor */ qdflags[unit].tab_res = *(short *)datap; break; default: /* * service tty 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); } } break; } return(0);} /* qdioctl */qdselect(dev, rw) dev_t dev; int rw;{ register s; register 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); } qdrsel[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); } qdrsel[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 <= tp->t_lowat) return(1); tp->t_wsel = u.u_procp; splx(s); return(0); } } splx(s); return(0);} /* qdselect() */extern qd_strategy();qdwrite(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register minor_dev; register unit; minor_dev = minor(dev); unit = (minor_dev >> 2) & 0x07; if (((minor_dev&0x03) != 0x02) && (qdflags[unit].inuse&CONS_DEV)) { /* * this is the console... */ tp = &qd_tty[minor_dev]; return ((*linesw[tp->t_line].l_write)(tp, uio)); } else if (qdflags[unit].inuse & GRAPHIC_DEV) { /* * this is a DMA xfer from user space */ return (physio(qd_strategy, &qdbuf[unit], dev, B_WRITE, minphys, uio)); } return (ENXIO);}qdread(dev, uio) dev_t dev; struct uio *uio;{ register struct tty *tp; register minor_dev; register unit; minor_dev = minor(dev); unit = (minor_dev >> 2) & 0x07; if ((minor_dev & 0x03) != 0x02 && qdflags[unit].inuse & CONS_DEV) { /* * this is the console */ tp = &qd_tty[minor_dev]; return ((*linesw[tp->t_line].l_read)(tp, uio)); } else if (qdflags[unit].inuse & GRAPHIC_DEV) { /* * this is a bitmap-to-processor xfer */ return (physio(qd_strategy, &qdbuf[unit], dev, B_READ, minphys, uio)); } return (ENXIO);}/***************************************************************** qd_strategy()... strategy routine to do DMA****************************************************************/qd_strategy(bp) register struct buf *bp;{ register struct dga *dga; register struct adder *adder; register unit; int QBAreg; int s; int cookie; unit = (minor(bp->b_dev) >> 2) & 0x07; /* * init pointers */ if ((QBAreg = ubasetup(0, bp, 0)) == 0) { printf("qd%d: qd_strategy: QBA setup error\n", unit); goto STRAT_ERR; } dga = (struct dga *) qdmap[unit].dga; s = spl5(); qdflags[unit].user_dma = -1; dga->csr |= DMA_IE; cookie = QBAreg & 0x3FFFF; dga->adrs_lo = (short) cookie; dga->adrs_hi = (short) (cookie >> 16); dga->bytcnt_lo = (short) bp->b_bcount; dga->bytcnt_hi = (short) (bp->b_bcount >> 16); while (qdflags[unit].user_dma) { sleep((caddr_t)&qdflags[unit].user_dma, QDPRIOR); } splx(s); ubarelse(0, &QBAreg); if (!(dga->csr & DMA_ERR)) { iodone(bp); return; }STRAT_ERR: adder = (struct adder *) qdmap[unit].adder; adder->command = CANCEL; /* cancel adder activity */ dga->csr &= ~DMA_IE; dga->csr &= ~0x0600; /* halt DMA (reset fifo) */ dga->csr |= DMA_ERR; /* clear error condition */ bp->b_flags |= B_ERROR; /* flag an error to physio() */ /* * if DMA was running, flush spurious intrpt */ if (dga->bytcnt_lo != 0) { dga->bytcnt_lo = 0; dga->bytcnt_hi = 0; DMA_SETIGNORE(DMAheader[unit]); dga->csr |= DMA_IE; } iodone(bp);} /* qd_strategy *//* * Start output to the console screen */qdstart(tp) register struct tty *tp;{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -