📄 qd.c
字号:
*/ qdflags[unit].config = *(u_short *)reg; /* * find an empty 64kb adrs boundary */ qdbase[unit] = (caddr_t) (qvmem[0] + QMEMSIZE - CHUNK); /* * find the cpusw entry that matches this machine. */ cpup = &cpusw[cpu]; while (!(BADADDR(qdbase[unit], sizeof(short)))) qdbase[unit] -= CHUNK; /* * tell QDSS which Q memory address base to decode */ mapix = (int) (VTOP(qdbase[unit]) - VTOP(qvmem[0])); ptep = (int *) QVmap[0] + mapix; phys_adr = (caddr_t)(((int)*ptep&0x001FFFFF)<<PGSHIFT); *(u_short *)reg = (u_short) ((int)phys_adr >> 16); /* * load QDSS adrs map with system addresses * of device regs */ qdmap[unit].template = qdbase[unit] + TMPSTART; qdmap[unit].adder = qdbase[unit] + ADDER; qdmap[unit].dga = qdbase[unit] + DGA; qdmap[unit].duart = qdbase[unit] + DUART; qdmap[unit].memcsr = qdbase[unit] + MEMCSR; qdmap[unit].red = qdbase[unit] + RED; qdmap[unit].blue = qdbase[unit] + BLUE; qdmap[unit].green = qdbase[unit] + GREEN; /* device init */ cursor[unit].x = 0; cursor[unit].y = 0; init_shared(unit); /* init shared memory */ setup_dragon(unit); /* init the ADDER/VIPER stuff */ ldcursor(unit, cons_cursor); /* load default cursor map */ setup_input(unit); /* init the DUART */ clear_qd_screen(unit); ldfont(unit); /* load the console font */ /* once only: turn on sync */ *(short *)qdmap[unit].memcsr |= SYNC_ON; }#endif /*notdef*/ } /* * The QDSS interrupts at HEX vectors xx0 (DMA) xx4 * (ADDER) and xx8 (DUART). Therefore, we take three * vectors from the vector pool, and then continue * to take them until we get a xx0 HEX vector. The * pool provides vectors in contiguous decending * order. */ vector = (uba_hd[0].uh_lastiv -= 4*3); /* take three vectors */ while (vector & 0x0F) { /* if lo nibble != 0.. */ /* ..take another vector */ vector = (uba_hd[0].uh_lastiv -= 4); } /* * setup DGA to do a DMA interrupt (transfer count = 0) */ dga = (struct dga *) qdmap[unit].dga; dga->csr = (short) HALT; /* disable everything */ dga->ivr = (short) vector; /* load intrpt base vector */ dga->bytcnt_lo = (short) 0; /* DMA xfer count = 0 */ dga->bytcnt_hi = (short) 0; /* * turn on DMA interrupts */ dga->csr &= ~SET_DONE_FIFO; dga->csr |= DMA_IE | DL_ENB; DELAY(20000); /* wait for the intrpt */ dga->csr = HALT; /* stop the wheels */ if (cvec != vector) /* if vector != base vector.. */ return(0); /* ..return = 'no device' */ /* * score this as an existing qdss */ qdcount++; return(sizeof(short)); /* return size of QDSS I/O page reg */} /* qdprobe */qdattach(ui) struct uba_device *ui;{ register unit; /* QDSS module # for this call */ unit = ui->ui_unit; /* get QDSS number */ /* * init "qdflags[]" for this QDSS */ qdflags[unit].inuse = 0; /* init inuse variable EARLY! */ qdflags[unit].mapped = 0; qdflags[unit].kernel_loop = -1; qdflags[unit].user_dma = 0; qdflags[unit].curs_acc = ACC_OFF; qdflags[unit].curs_thr = 128; qdflags[unit].tab_res = 2; /* default tablet resolution factor */ qdflags[unit].duart_imask = 0; /* init shadow variables */ qdflags[unit].adder_ie = 0; /* * init structures used in kbd/mouse interrupt service. This code must * come after the "init_shared()" routine has run since that routine * inits the eq_header[unit] structure used here. */ /* * init the "latest mouse report" structure */ last_rep[unit].state = 0; last_rep[unit].dx = 0; last_rep[unit].dy = 0; last_rep[unit].bytcnt = 0; /* * init the event queue (except mouse position) */ eq_header[unit]->header.events = (struct _vs_event *)((int)eq_header[unit] + sizeof(struct qdinput)); eq_header[unit]->header.size = MAXEVENTS; eq_header[unit]->header.head = 0; eq_header[unit]->header.tail = 0; /* * open exclusive for graphics device. */ qdopened[unit] = 0;} /* qdattach *//*ARGSUSED*/qdopen(dev, flag) dev_t dev; int flag;{ register struct uba_device *ui; /* ptr to uba structures */ register struct dga *dga; /* ptr to gate array struct */ register struct tty *tp; struct duart *duart; int unit; int minor_dev; minor_dev = minor(dev); /* get QDSS minor device number */ unit = minor_dev >> 2; /* * check for illegal conditions */ ui = qdinfo[unit]; /* get ptr to QDSS device struct */ if (ui == 0 || ui->ui_alive == 0) return(ENXIO); /* no such device or address */ duart = (struct duart *) qdmap[unit].duart; dga = (struct dga *) qdmap[unit].dga; if ((minor_dev & 0x03) == 2) { /* * this is the graphic device... */ if (qdopened[unit] != 0) return(EBUSY); else qdopened[unit] = 1; qdflags[unit].inuse |= GRAPHIC_DEV; /* graphics dev is open */ /* * enble kbd & mouse intrpts in DUART mask reg */ qdflags[unit].duart_imask |= 0x22; duart->imask = qdflags[unit].duart_imask; } else { /* * this is the console */ qdflags[unit].inuse |= CONS_DEV; /* mark console as open */ dga->csr |= CURS_ENB; qdflags[unit].duart_imask |= 0x02; duart->imask = qdflags[unit].duart_imask; /* * some setup for tty handling */ tp = &qd_tty[minor_dev]; tp->t_addr = ui->ui_addr; tp->t_oproc = qdstart; if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); tp->t_ispeed = B9600; tp->t_ospeed = B9600; tp->t_state = TS_ISOPEN | TS_CARR_ON; tp->t_iflag = TTYDEF_IFLAG; tp->t_oflag = TTYDEF_OFLAG; tp->t_lflag = TTYDEF_LFLAG; tp->t_cflag = TTYDEF_CFLAG; } /* * enable intrpts, open line discipline */ dga->csr |= GLOBAL_IE; /* turn on the interrupts */ return ((*linesw[tp->t_line].l_open)(dev, tp)); } dga->csr |= GLOBAL_IE; /* turn on the interrupts */ return(0);} /* qdopen *//*ARGSUSED*/qdclose(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p;{ register struct tty *tp; register struct qdmap *qd; register int *ptep; struct dga *dga; /* gate array register map pointer */ struct duart *duart; struct adder *adder; int unit; int minor_dev; u_int mapix; int i; /* SIGNED index */ minor_dev = minor(dev); /* get minor device number */ unit = minor_dev >> 2; /* get QDSS number */ qd = &qdmap[unit]; if ((minor_dev & 0x03) == 2) { /* * this is the graphic device... */ if (qdopened[unit] != 1) return(EBUSY); else qdopened[unit] = 0; /* allow it to be re-opened */ /* * re-protect device memory */ if (qdflags[unit].mapped & MAPDEV) { /* * 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_V | PG_KW; /* * ADDER */ 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_V | PG_KW; /* * 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_V | PG_KW; } /* * re-protect DMA buffer and free the map registers */ if (qdflags[unit].mapped & MAPDMA) { dga = (struct dga *) qdmap[unit].dga; adder = (struct adder *) qdmap[unit].adder; dga->csr &= ~DMA_IE; dga->csr &= ~0x0600; /* kill DMA */ adder->command = CANCEL; /* * 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; dga->csr &= ~DMA_IE; } ptep = (int *) ((VTOP(DMAheader[unit]*4)) + (mfpr(SBR)|0x80000000)); for (i = 0; i < btop(DMAbuf_size); i++, ptep++) *ptep = (*ptep & ~PG_PROT) | PG_V | PG_KW; ubarelse(0, &Qbus_unmap[unit]); } /* * re-protect 1K (2 pages) event queue */ if (qdflags[unit].mapped & MAPEQ) { ptep = (int *) ((VTOP(eq_header[unit])*4) + (mfpr(SBR)|0x80000000)); *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; ptep++; *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; } /* * re-protect scroll param area and disable scroll intrpts */ if (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; adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie &= ~FRAME_SYNC; adder->interrupt_enable = qdflags[unit].adder_ie; } /* * re-protect color map write buffer area and kill intrpts */ if (qdflags[unit].mapped & MAPCOLOR) { ptep = (int *) ((VTOP(color_buf[unit]) * 4) + (mfpr(SBR) | 0x80000000)); *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; ptep++; *ptep = (*ptep & ~PG_PROT) | PG_KW | PG_V; color_buf[unit]->status = 0; adder = (struct adder *) qdmap[unit].adder; qdflags[unit].adder_ie &= ~VSYNC; adder->interrupt_enable = qdflags[unit].adder_ie; } mtpr(TBIA, 0); /* flag everything now unmapped */ qdflags[unit].mapped = 0; qdflags[unit].inuse &= ~GRAPHIC_DEV; qdflags[unit].curs_acc = ACC_OFF; qdflags[unit].curs_thr = 128; /* * restore the console */ dga = (struct dga *) qdmap[unit].dga; adder = (struct adder *) qdmap[unit].adder; dga->csr &= ~DMA_IE; dga->csr &= ~0x0600; /* halt the DMA! (just in case...) */ dga->csr |= DMA_ERR; /* clear error condition */ adder->command = CANCEL; /* * 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; dga->csr &= ~DMA_IE; } init_shared(unit); /* init shared memory */ setup_dragon(unit); /* init ADDER/VIPER */ ldcursor(unit, cons_cursor); /* load default cursor map */ setup_input(unit); /* init the DUART */ ldfont(unit); cursor[unit].x = 0; cursor[unit].y = 0; /* * shut off the mouse rcv intrpt and turn on kbd intrpts */ duart = (struct duart *) qdmap[unit].duart; qdflags[unit].duart_imask &= ~(0x20); qdflags[unit].duart_imask |= 0x02; duart->imask = qdflags[unit].duart_imask; /* * shut off interrupts if all is closed */ if (!(qdflags[unit].inuse & CONS_DEV)) { dga = (struct dga *) qdmap[unit].dga; dga->csr &= ~(GLOBAL_IE | DMA_IE); } } else { /* * this is the console */ tp = &qd_tty[minor_dev]; (*linesw[tp->t_line].l_close)(tp, flag); ttyclose(tp); tp->t_state = 0; qdflags[unit].inuse &= ~CONS_DEV; /* * if graphics device is closed, kill interrupts */ if (!(qdflags[unit].inuse & GRAPHIC_DEV)) { dga = (struct dga *) qdmap[unit].dga; dga->csr &= ~(GLOBAL_IE | DMA_IE); } } return(0);} /* qdclose */qdioctl(dev, cmd, datap, flags) dev_t dev; int cmd; register caddr_t datap; int flags;{ register int *ptep; /* page table entry pointer */ register int mapix; /* QVmap[] page table index */ register struct _vs_event *event; register struct tty *tp; register i; struct qdmap *qd; /* pointer to device map struct */ struct dga *dga; /* Gate Array reg structure pntr */ struct duart *duart; /* DUART reg structure pointer */ struct adder *adder; /* ADDER reg structure pointer */ struct prgkbd *cmdbuf; struct prg_cursor *curs; struct _vs_cursor *pos; int unit = minor(dev) >> 2; /* number of caller's QDSS */ u_int minor_dev = minor(dev); int error; int s; short *temp; /* a pointer to template RAM */ /* * service graphic device ioctl commands */ switch (cmd) { case QD_GETEVENT: /* * extract the oldest event from the event queue */ if (ISEMPTY(eq_header[unit])) { event = (struct _vs_event *) datap; event->vse_device = VSE_NULL; break; } event = (struct _vs_event *) GETBEGIN(eq_header[unit]); s = spl5(); GETEND(eq_header[unit]); splx(s); bcopy((caddr_t)event, datap, sizeof(struct _vs_event)); break; case QD_RESET: /* * init the dragon stuff, DUART, and driver variables */ init_shared(unit); /* init shared memory */ setup_dragon(unit); /* init the ADDER/VIPER stuff */ clear_qd_screen(unit); ldcursor(unit, cons_cursor); /* load default cursor map */ ldfont(unit); /* load the console font */ setup_input(unit); /* init the DUART */ break; case QD_SET: /* * init the DUART and driver variables */ init_shared(unit); setup_input(unit); break; case QD_CLRSCRN: /* * clear the QDSS screen. (NOTE that this reinits the dragon) */#ifdef notdef /* has caused problems and isn't necessary */ setup_dragon(unit); clear_qd_screen(unit);#endif break; case QD_WTCURSOR: /* * load a cursor into template RAM */ ldcursor(unit, (short *)datap); break; case QD_RDCURSOR: temp = (short *) qdmap[unit].template; /* * cursor is 32 WORDS from the end of the 8k WORD... * ...template space */ temp += (8 * 1024) - 32; for (i = 0; i < 32; ++i, datap += sizeof(short)) *(short *)datap = *temp++; break; case QD_POSCURSOR: /* * position the mouse cursor */ dga = (struct dga *) qdmap[unit].dga; pos = (struct _vs_cursor *) datap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -