📄 sg.c
字号:
*(u_long *) &sgfcc->cbcsr = (u_long) HALT;/* Enable FIFO compression interrupt *//* set fcc to display list mode */ sgaddr->nb_int_msk |= SINT_VS; sgfcc->cbcsr &= ~FLUSH; *(u_long *)&sgfcc->put = (u_long) 0; sgfcc->thresh = 0x100; *(unsigned long *) &sgfcc->cbcsr |= (unsigned long)(((sgfcc->icsr|ENTHRSH) << 16)|DL_ENB); DELAY(20000); /* wait */ if (cvec && cvec != 0x200) cvec -= 4; return(8);}/****************************************************************** ** ** ** Routine to attach to the graphic device. ** ** ** ******************************************************************/sgattach(ui) struct uba_device *ui;{ register int *pte; int i; sg_keyboard.hold = 0; /* "Hold Screen" key is pressed if 1 *//* * init "sgflags" */ sgflags.inuse = 0; /* init inuse variable EARLY! */ sgflags.mapped = 0; sgflags.kernel_loop = -1; /* default is now kern_loop on */ sgflags.user_fifo = 0; sgflags.curs_acc = ACC_OFF; sgflags.curs_thr = 128; sgflags.tab_res = 2; /* default tablet resolution factor */ sgflags.duart_imask = 0; /* init shadow variables */ sgflags.adder_ie = 0;/* * init structures used in kbd/mouse interrupt routine. This code must * come after the "sg_init_shared()" routine has run since that routine inits * the eq_header structure used here. *//* init the "latest mouse report" structure */ last_rep.state = 0; last_rep.dx = 0; last_rep.dy = 0; last_rep.bytcnt = 0;/* init the event queue (except mouse position) */ eq_header->header.events = (struct _vs_event *) ((int)eq_header + sizeof(struct sginput)); eq_header->header.size = MAXEVENTS; eq_header->header.head = 0; eq_header->header.tail = 0;/* init single process access lock switch */ sg_open = 0;/* * Do the following only for the color display. */ if (v_consputc == sgputc) {/* * Map the bitmap for use by users. */ pte = (int *)(SGMEMmap[0]); for( i=0 ; i<192 ; i++, pte++ ) *pte = (*pte & ~PG_PROT) | PG_UW | PG_V; }}/****************************************************************** ** ** ** Routine to open the graphic device. ** ** ** ******************************************************************/extern struct pdma sspdma[];extern int ssparam();/*ARGSUSED*/sgopen(dev, flag) dev_t dev;{ register int unit = minor(dev); register struct tty *tp; register struct nb_regs *sgiaddr = (struct nb_regs *)nexus; register struct vdac *sgvdac; register struct fcc *sgfcc; register struct adder *sgaddr = (struct adder *) sgmap.adder; sgvdac = (struct vdac *)sgmap.vdac; sgfcc = (struct fcc *) sgmap.fcc;/* * The graphics device can be open only by one person */ if (unit == 1) { if (sg_open != 0) return(EBUSY); else sg_open = 1; sgflags.inuse |= GRAPHIC_DEV; /* graphics dev is open */ sgflags.adder_ie |= VSYNC; *(unsigned long *)&sgaddr->interrupt_enable = (unsigned long)((sgaddr->status << 16) | sgflags.adder_ie); } else { sgflags.inuse |= CONS_DEV; /* mark console as open */ } if ((unit == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &ss_tty[unit]; if (tp->t_state&TS_XCLUDE && u.u_uid!=0) return (EBUSY); tp->t_addr = (caddr_t)&sspdma[unit]; tp->t_oproc = sgstart; /*--------------------------------------------------------------------- * Look at the compatibility mode to specify correct default parameters * and to insure only standard specified functionality. */ if ((u.u_procp->p_progenv == A_SYSV) || (u.u_procp->p_progenv == A_POSIX)) { flag |= O_TERMIO; tp->t_line = TERMIODISC; } /*-------------------------------------------------------------------- * Set state bit to tell tty.c not to assign this line as the * controlling terminal for the process which opens this line. */ if ((flag & O_NOCTTY) && (u.u_procp->p_progenv == A_POSIX)) tp->t_state |= TS_ONOCTTY; if ((tp->t_state&TS_ISOPEN) == 0) { ttychars(tp); tp->t_state = TS_ISOPEN|TS_CARR_ON; tp->t_cflag = tp->t_cflag_ext = B4800; tp->t_iflag_ext = 0; tp->t_oflag_ext = 0; tp->t_lflag_ext = 0; if( unit == 0 ) { /*---------------------------------------------------- * Ultrix defaults to a "COOKED" mode on the first * open, while termio defaults to a "RAW" style. * Base this decision by a flag set in the termio * emulation routine for open, or set by an explicit * ioctl call. */ if ( flag & O_TERMIO ) { /*-------------------------------------- * Provide a termio style environment. * "RAW" style by default. */ tp->t_flags = RAW; tp->t_iflag = 0; tp->t_oflag = 0; tp->t_cflag |= CS8|CREAD|HUPCL; tp->t_lflag = 0; /*------------------------------------- * Change to System V line discipline.*/ tp->t_line = TERMIODISC; /*----------------------------------------- * The following three control chars have * different default values than ULTRIX. */ tp->t_cc[VERASE] = '#'; tp->t_cc[VKILL] = '@'; tp->t_cc[VINTR] = 0177; tp->t_cc[VMIN] = 6; tp->t_cc[VTIME] = 1; } else { /*-------------------------------------- * Provide a backward compatible ULTRIX * environment. "COOKED" style. */ tp->t_flags = IFLAGS; tp->t_iflag = IFLAG; tp->t_oflag = OFLAG; tp->t_lflag = LFLAG; tp->t_cflag |= CFLAG; } } else { tp->t_flags = RAW; tp->t_iflag = 0; tp->t_oflag = 0; tp->t_cflag |= CS8|CREAD|HUPCL; tp->t_lflag = 0; } if(tp != &sm_tty) ssparam(unit); else tp->t_iflag |= IXOFF; /* flow control for qconsole */ } sgiaddr->nb_int_msk |= SINT_VS; /* enable interrupts *//* * Process line discipline specific open if its not the mouse. */ if (unit != 1) return ((*linesw[tp->t_line].l_open)(dev, tp)); else { sg_mouseon = 1; return(0); }}/****************************************************************** ** ** ** Routine to close the graphic device. ** ** ** ******************************************************************//*ARGSUSED*/sgclose(dev, flag) dev_t dev; int flag;{ register struct tty *tp; register int unit = minor(dev); unit = minor(dev); if ((unit == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &ss_tty[unit];/* * If unit is not the mouse call the line disc. otherwise clear the state * flag, and put the keyboard into down/up. */ if( unit != 1 ){ (*linesw[tp->t_line].l_close)(tp); ttyclose(tp); sgflags.inuse &= ~CONS_DEV; sg_keyboard.cntrl = sg_keyboard.shift = 0; } else { sg_mouseon = 0; if (sg_open != 1) return(EBUSY); else sg_open = 0; /* mark the graphics device available */ sgflags.inuse &= ~GRAPHIC_DEV; sg_init_shared(); /* init shared memory */ sg_load_colormaps(); /* Load B/F and cursor color maps */ sg_load_cursor( def_cur); /* load default cursor map */ sg_ld_font(); /* load the console font */ cursor.x = 0; cursor.y = 0; if (sg_video_off) sg_video_on(); } tp->t_state = 0; /* Remove termio flags that do not map */ tp->t_iflag &= ~TERMIO_ONLY_IFLAG; tp->t_oflag &= ~TERMIO_ONLY_OFLAG; tp->t_cflag &= ~TERMIO_ONLY_CFLAG; tp->t_lflag &= ~TERMIO_ONLY_LFLAG;}/****************************************************************** ** ** ** Routine to read from the graphic device. ** ** ** ******************************************************************/extern sg_strategy();sgread(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) != 1 && sgflags.inuse & CONS_DEV) { if ((minor_dev == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &ss_tty[minor_dev]; return ((*linesw[tp->t_line].l_read)(tp, uio)); }/* * else this must be a FIFO xfer from user space */ else if (sgflags.inuse & GRAPHIC_DEV) { return (physio(sg_strategy, &sgbuf[unit], dev, B_READ, minphys, uio)); }}/****************************************************************** ** ** ** Routine to write to the graphic device. ** ** ** ******************************************************************/extern sg_strategy();sgwrite(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) != 1 && sgflags.inuse & CONS_DEV) { if ((minor_dev == 2) && (major(dev) == CONSOLEMAJOR)) tp = &sm_tty; else tp = &ss_tty[minor_dev]; return ((*linesw[tp->t_line].l_write)(tp, uio)); }/* * else this must be a FIFO xfer from user space */ else if (sgflags.inuse & GRAPHIC_DEV) { return (physio(sg_strategy, &sgbuf[unit], dev, B_WRITE, minphys, uio)); }}/****************************************************************** ** ** ** Strategy routine to do FIFO ** ** ** ******************************************************************/sg_strategy(bp)register struct buf *bp;{ register int npf, o; register struct pte *pte; register struct pte *mpte; register struct proc *rp; register struct fcc *sgfcc; register struct adder *sgaddr; register u_short *bufp; int s; int unit, i; unsigned v; unit = (minor(bp->b_dev) >> 2) & 0x07; s = spl5();/* * following code figures out the proper ptes to * remap into system space so interrupt routine can * copy into buf structure. */ v = btop(bp->b_un.b_addr); o = (int)bp->b_un.b_addr & PGOFSET; npf = btoc(bp->b_bcount + o); rp = bp->b_flags&B_DIRTY ? &proc[2] : bp->b_proc; if ((bp->b_flags & B_PHYS) == 0) { sg_fifo_addr = bp->b_un.b_addr; } else { int user_addr = 0; if (bp->b_flags & B_UAREA) pte = &rp->p_addr[v]; else if (bp->b_flags & B_PAGET) pte = &Usrptmap[btokmx((struct pte *)bp->b_un.b_addr)]; else if ((bp->b_flags & B_SMEM) && /* SHMEM */ ((bp->b_flags & B_DIRTY) == 0)) pte = ((struct smem *)rp)->sm_ptaddr + v; else { pte = (struct pte *)0; user_addr++; } sg_fifo_addr = (char *)((int)SG_bufmap + (int)o); mpte = (struct pte *)sgbufmap; for (i = 0; i< npf; i++, v++) { if (user_addr && (((int)pte & PGOFSET) < CLSIZE*sizeof(struct pte) || pte->pg_pfnum == 0)) pte = vtopte(rp, v); if(pte->pg_pfnum == 0) panic("sg: zero pfn in pte"); *(int *)mpte++ = pte++->pg_pfnum | PG_V | PG_KW; mtpr(TBIS, (char *) SG_bufmap + (i*NBPG)); } *(int *)mpte = 0; mtpr(TBIS, (char *)SG_bufmap + (i * NBPG)); } sgfcc = (struct fcc *) sgmap.fcc; sgaddr = (struct adder *) sgmap.adder; sg_ptr = sgmap.fiforam; sgflags.user_fifo = -1; if (!(bp->b_flags & B_READ)) { nbytes_req = bp->b_bcount; bcopy(sg_fifo_addr, sg_ptr, 0x020); sgfcc->put += 0x010; sg_fifo_addr += 0x020; sg_ptr += 0x020; nbytes_left = nbytes_req - 0x020; } sgfcc->icsr |= ENTHRSH; while (sgflags.user_fifo) { sleep((caddr_t)&sgflags.user_fifo, SGPRIOR); } splx(s); iodone(bp);}/****************************************************************** ** ** ** Mouse activity select routine. ** ** ** ******************************************************************/sgselect(dev, rw)dev_t dev;{ register int s = spl5(); register int unit = minor(dev); register struct tty *tp; switch(rw) { case FREAD: /* event available */ if (unit == 1) { if(!(ISEMPTY(eq_header))) { splx(s); return(1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -