⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qv.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		om_switch = m_switch;		qp->mswitches = m_switch;	}	/* if we have proc waiting, and event has happened, wake him up */	if(qvrsel && (qp->ihead != qp->itail)) {		selwakeup(qvrsel,0);		qvrsel = 0;	}	/*	 * Okay we can take another hit now	 */	qv_ipl_lo = 1;}/* * Start  transmission */qvstart(tp)	register struct tty *tp;{	register int unit, c;	register struct tty *tp0;	int s;	unit = minor(tp->t_dev);#ifdef CONS_HACK	tp0 = &qv_tty[(unit&0xfc)+QVPCONS];#endif	unit = QVCHAN(unit);	s = spl5();	/*	 * If it's currently active, or delaying, no need to do anything.	 */	if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))		goto out;	/*	 * Display chars until the queue is empty, if the second subchannel	 * is open direct them there. Drop characters from subchannels other	 * than 0 on the floor.	 */	while( tp->t_outq.c_cc ) {		c = getc(&tp->t_outq);		if (unit == QVKEYBOARD)#ifdef CONS_HACK			if( tp0->t_state & TS_ISOPEN ){				(*linesw[tp0->t_line].l_rint)(c, tp0);			} else#endif				qvputchar( c & 0xff );	}	/*	 * Position the cursor to the next character location.	 */	qv_pos_cur( qv_scn->col*8, qv_scn->row*15 );	/*	 * If there are sleepers, and output has drained below low	 * water mark, wake up the sleepers.	 */	if ( tp->t_outq.c_cc<= tp->t_lowat ) {		if (tp->t_state&TS_ASLEEP){			tp->t_state &= ~TS_ASLEEP;			wakeup((caddr_t)&tp->t_outq);		}	}	tp->t_state &= ~TS_BUSY;out:	splx(s);}/* * Stop output on a line, e.g. for ^S/^Q or output flush. *//*ARGSUSED*/qvstop(tp, flag)	register struct tty *tp;{	register int s;	/*	 * Block input/output interrupts while messing with state.	 */	s = spl5();	if (tp->t_state & TS_BUSY) {		if ((tp->t_state&TS_TTSTOP)==0) {			tp->t_state |= TS_FLUSH;		} else			tp->t_state &= ~TS_BUSY;	}	splx(s);}qvputc(c)char c;{	qvputchar(c);	if (c == '\n')		qvputchar('\r');}/* * Routine to display a character on the screen.  The model used is a  * glass tty.  It is assummed that the user will only use this emulation * during system boot and that the screen will be eventually controlled * by a window manager. * */qvputchar( c )register char c;{	register char *b_row, *f_row;	register int i;	register short *scanline;	register int ote = 128;	register struct qv_info *qp = qv_scn;	/*	 * This routine may be called in physical mode by the dump code	 * so we check and punt if that's the case.	 */	if( (mfpr(MAPEN) & 1) == 0 )		return;	c &= 0x7f;	switch ( c ) {	case '\t':				/* tab		*/		for( i = 8 - (qp->col & 0x7) ; i > 0 ; i-- )			qvputchar( ' ' );		break;	case '\r':				/* return	*/		qp->col = 0;		break;	case '\010':				/* backspace	*/		if( --qp->col < 0 )			qp->col = 0;		break;	case '\n':				/* linefeed	*/		if( qp->row+1 >= qp->max_row )			qvscroll();		else			qp->row++;		/*		* Position the cursor to the next character location.		*/		qv_pos_cur( qp->col*8, qp->row*15 );		break;	case '\007':				/* bell		*/                /*                 * We don't do anything to the keyboard until after                 * autoconfigure.                 */		if( qp->qvaddr )			qv_key_out( LK_RING_BELL );		return;	default:		if( c >= ' ' && c <= '~' ) {                        scanline = qp->scanmap;                        b_row = qp->bitmap+(scanline[qp->row*15]&0x3ff)*128+qp->col;			i = c - ' ';			if( i < 0 || i > 95 )				i = 0;			else				i *= 15;			f_row = (char *)((int)q_font + i);		/*			for( i=0 ; i<15 ; i++ , b_row += 128, f_row++ )				*b_row = *f_row;*/			/* inline expansion for speed */			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			*b_row = *f_row++; b_row += ote;			if( ++qp->col >= qp->max_col ) {				qp->col = 0 ;				if( qp->row+1 >= qp->max_row )					qvscroll();				else					qp->row++;			}		}		break;	}}/* * Position the cursor to a particular spot. */qv_pos_cur( x, y)register int x,y;{	register struct qvdevice *qvaddr;	register struct qv_info *qp = qv_scn;	register index;	if( qvaddr = qp->qvaddr ) {		if( y < 0 || y > qp->max_cur_y )			y = qp->max_cur_y;		if( x < 0 || x > qp->max_cur_x )			x = qp->max_cur_x;		qp->cursor.x = x;		/* keep track of real cursor*/		qp->cursor.y = y;		/* position, indep. of mouse*/		qvaddr->qv_crtaddr = 10;	/* select cursor start reg */		qvaddr->qv_crtdata = y & 0xf;		qvaddr->qv_crtaddr = 11;	/* select cursor end reg */		qvaddr->qv_crtdata = y & 0xf;		qvaddr->qv_crtaddr = 14;	/* select cursor y pos. */		qvaddr->qv_crtdata = y >> 4;		qvaddr->qv_xcur = x;		/* pos x axis	*/		/*		 * If the mouse is being used then we change the mode of		 * cursor display based on the pixels under the cursor		 */		if( mouseon ) {			index = y*128 + x/8;			if( qp->bitmap[ index ] && qp->bitmap[ index+128 ] )				qvaddr->qv_csr &= ~QV_CUR_MODE;			else				qvaddr->qv_csr |=  QV_CUR_MODE;		}	}}/* * Scroll the bitmap by moving the scanline map words. This could * be done by moving the bitmap but it's much too slow for a full screen. * The only drawback is that the scanline map must be reset when the user  * wants to do graphics. */qvscroll(){	short tmpscanlines[15];	register char *b_row;	register short *scanline;	register struct qv_info *qp = qv_scn;	/*	 * If the mouse is on we don't scroll so that the bit map	 * remains sane.	 */	if( mouseon ) {		qp->row = 0;		return;	}	/*	 * Save the first 15 scanlines so that we can put them at	 * the bottom when done.	 */	bcopy((caddr_t)qp->scanmap, (caddr_t)tmpscanlines, sizeof tmpscanlines);	/*	 * Clear the wrapping line so that it won't flash on the bottom	 * of the screen.	 */        scanline = qp->scanmap;        b_row = qp->bitmap+(*scanline&0x3ff)*128;	bzero( b_row, 1920 );	/*	 * Now move the scanlines down 	 */	bcopy((caddr_t)(qp->scanmap+15), (caddr_t)qp->scanmap,	      (qp->row * 15) * sizeof (short) );	/*	 * Now put the other lines back	 */	bcopy((caddr_t)tmpscanlines, (caddr_t)(qp->scanmap+(qp->row * 15)),	      sizeof (tmpscanlines) );}/* * Output to the keyboard. This routine status polls the transmitter on the * keyboard to output a code. The timer is to avoid hanging on a bad device. */qv_key_out(c)	u_short c;{	int timer = 30000;	register struct qv_info *qp = qv_scn;	if (qp->qvaddr) {		while ((qp->qvaddr->qv_uartstatus & 0x4) == 0  && timer--)			;		qp->qvaddr->qv_uartdata = c;	}}/* * Virtual console initialization. This routine sets up the qvss so that it can * be used as the system console. It is invoked before autoconfig and has to do * everything necessary to allow the device to serve as the system console.  * In this case it must map the q-bus and device areas and initialize the qvss  * screen. */qvcons_init(){        struct percpu *pcpu;            /* pointer to percpu structure  */	register struct qbus *qb;        struct qvdevice *qvaddr;        /* device pointer               */        short *devptr;                  /* virtual device space         */	extern cnputc();		/* standard serial console putc */#define QVSSCSR 017200	/*	 * If secondary console already configured,	 * don't override the previous one.	 */	if (v_putc != cnputc)		return 0;        /*         * find the percpu entry that matches this machine.         */        for( pcpu = percpu ; pcpu && pcpu->pc_cputype != cpu ; pcpu++ )                ;        if( pcpu == NULL )                return 0;	if (pcpu->pc_io->io_type != IO_QBUS)		return 0;        /*         * Found an entry for this cpu. Because this device is Microvax specific         * we assume that there is a single q-bus and don't have to worry about         * multiple adapters.         *         * Map the device registers.         */	qb = (struct qbus *)pcpu->pc_io->io_details;	ioaccess(qb->qb_iopage, UMEMmap[0] + qb->qb_memsize, UBAIOPAGES * NBPG);        /*         * See if the qvss is there.         */        devptr = (short *)((char *)umem[0] + (qb->qb_memsize * NBPG));        qvaddr = (struct qvdevice *)((u_int)devptr + ubdevreg(QVSSCSR));        if (badaddr((caddr_t)qvaddr, sizeof(short)))                return 0;        /*         * Okay the device is there lets set it up         */        if (!qv_setup(qvaddr, 0, 0))		return 0;	v_putc = qvputc;        consops = &cdevsw[QVSSMAJOR];	return 1;}/* * Do the board specific setup */qv_setup(qvaddr, unit, probed)struct qvdevice *qvaddr;int unit;int probed;{        caddr_t qvssmem;		/* pointer to the display mem   */        register i;			/* simple index                 */	register struct qv_info *qp;        register int *pte;        struct percpu *pcpu;            /* pointer to percpu structure  */	register struct qbus *qb;        /*         * find the percpu entry that matches this machine.         */        for( pcpu = percpu ; pcpu && pcpu->pc_cputype != cpu ; pcpu++ )                ;        if( pcpu == NULL )                return(0);        /*         * Found an entry for this cpu. Because this device is Microvax specific         * we assume that there is a single q-bus and don't have to worry about         * multiple adapters.         *         * Map the device memory.         */	qb = (struct qbus *)pcpu->pc_io->io_details;        i = (u_int)(qvaddr->qv_csr & QV_MEM_BANK) << 7;	ioaccess(qb->qb_maddr + i, QVmap[unit], 512 * NBPG);	qvssmem = qvmem[unit];        pte = (int *)(QVmap[unit]);        for (i=0; i < 512; i++, pte++)                *pte = (*pte & ~PG_PROT) | PG_UW | PG_V;        qv_scn = (struct qv_info *)((u_int)qvssmem + 251*1024);	qp = qv_scn;        if( (qvaddr->qv_csr & QV_19INCH) && qv_def_scrn == 0)                qv_def_scrn = 1;        *qv_scn = qv_scn_defaults[ qv_def_scrn ];	if (probed)		qp->qvaddr = qvaddr; 	qp->bitmap = qvssmem;        qp->scanmap = (short *)((u_int)qvssmem + 254*1024);        qp->cursorbits = (short *)((u_int)qvssmem + 256*1024-32);	/* set up event queue for later */	qp->ibuff = (vsEvent *)qp - QVMAXEVQ;	qp->iqsize = QVMAXEVQ;	qp->ihead = qp->itail = 0;        /*         * Setup the crt controller chip.         */        for( i=0 ; i<16 ; i++ ) {                qvaddr->qv_crtaddr = i;                qvaddr->qv_crtdata = qv_crt_parms[ qv_def_scrn ][ i ];        }        /*         * Setup the display.         */        qv_init( qvaddr );        /*         * Turn on the video         */        qvaddr->qv_csr |= QV_VIDEO_ENA ;	return 1;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -