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

📄 qd.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	register which_unit, unit, c;	int s;	unit = minor(tp->t_dev);	which_unit = (unit >> 2) & 0x3;	unit &= 0x03;	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.	* Drop input from anything but the console	* device on the floor.		*	* XXX - this loop is done at spltty.	*	*/	while (tp->t_outq.c_cc) {		c = getc(&tp->t_outq);		if (unit == 0)			blitc(which_unit, (u_char)c);	}	/*	* 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);} /* qdstart *//*ARGSUSED*/qdstop(tp, flag)	register struct tty *tp;	int flag;{	register int s;	s = spl5();	/* block intrpts during state modification */	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);}/* *  Output a character to the QDSS screen */blitc(unit, chr)	register unit;	register u_char chr;{	register struct adder *adder;	register struct dga *dga;	register int i;	int nograph = !(qdflags[unit].inuse&GRAPHIC_DEV);	static short inescape[NQD];	adder = (struct adder *)qdmap[unit].adder;	dga = (struct dga *) qdmap[unit].dga;	/* 	 * BSD comment: this (&=0177) defeats the extended character 	 * set code for the glass tty, but if i had the time i would 	 * spend it ripping out the code completely.  This driver	 * is too big for its own good.	 */	chr &= 0177;	/*	 * Cursor addressing (so vi will work).	 * Decode for "\E=%.%." cursor motion description.	 * Corresponds to type "qdcons" in /etc/termcap:	 *	 *    qd|qdss|qdcons|qdss glass tty (4.4 BSD):\	 *      :am:do=^J:le=^H:bs:cm=\E=%.%.:cl=1^Z:co#128:li#57::nd=^L:up=^K:	 *	 */	if (inescape[unit] && nograph) {			switch (inescape[unit]++) {		case 1:			if (chr != '=') {				/* abort escape sequence */				inescape[unit] = 0;				blitc(unit, chr);			}			return;		case 2:			/* position row */			cursor[unit].y = CHAR_HEIGHT * chr;			if (cursor[unit].y > 863 - CHAR_HEIGHT)				cursor[unit].y = 863 - CHAR_HEIGHT;			dga->y_cursor = TRANY(cursor[unit].y);			return;		case 3:			/* position column */			cursor[unit].x = CHAR_WIDTH * chr;			if (cursor[unit].x > 1024 - CHAR_WIDTH)				cursor[unit].x = 1023 - CHAR_WIDTH;			dga->x_cursor = TRANX(cursor[unit].x);			inescape[unit] = 0;			return;		default:			inescape[unit] = 0;			blitc(unit, chr);		}	}	switch (chr) {	case '\r':			/* return char */		cursor[unit].x = 0;		if (nograph)			dga->x_cursor = TRANX(cursor[unit].x);		return;	case '\t':			/* tab char */		for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) {			blitc(unit, ' ');		}		return;	case '\n':			/* line feed char */		if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) {			if (nograph) {				cursor[unit].y -= CHAR_HEIGHT;				scroll_up(adder);			} else				cursor[unit].y = 0;		}		if (nograph)			dga->y_cursor = TRANY(cursor[unit].y);		return;	case '\b':			/* backspace char */		if (cursor[unit].x > 0) {			cursor[unit].x -= CHAR_WIDTH;			if (nograph)				dga->x_cursor = TRANX(cursor[unit].x);		}		return;	case CTRL('k'):		/* cursor up */		if (nograph && cursor[unit].y > 0) {			cursor[unit].y -= CHAR_HEIGHT;			dga->y_cursor = TRANY(cursor[unit].y);		}		return;	case CTRL('^'):		/* home cursor */		if (nograph) {			cursor[unit].x = 0;			dga->x_cursor = TRANX(cursor[unit].x);			cursor[unit].y = 0;			dga->y_cursor = TRANY(cursor[unit].y);		}		return;	case CTRL('l'):		/* cursor right */		if (nograph && cursor[unit].x < 1023 - CHAR_WIDTH) {			cursor[unit].x += CHAR_WIDTH;			dga->x_cursor = TRANX(cursor[unit].x);		}		return;	case CTRL('z'):		/* clear screen */		if (nograph) {			setup_dragon(unit);  				clear_qd_screen(unit);			/* home cursor - termcap seems to assume this */			cursor[unit].x = 0;			dga->x_cursor = TRANX(cursor[unit].x);			cursor[unit].y = 0;			dga->y_cursor = TRANY(cursor[unit].y);		}		return;	case '\033':		/* start escape sequence */		if (nograph)			inescape[unit] = 1;		return;	default:		if ((chr < ' ') || (chr > '~'))			return;	}	/*	 * setup VIPER operand control registers  	 */	write_ID(adder, CS_UPDATE_MASK, 0x0001);  /* select plane #0 */	write_ID(adder, SRC1_OCR_B,	EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);	write_ID(adder, CS_UPDATE_MASK, 0x00FE);  /* select other planes */	write_ID(adder, SRC1_OCR_B,	EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY);	write_ID(adder, CS_UPDATE_MASK, 0x00FF);  /* select all planes */	write_ID(adder, DST_OCR_B,	EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);	write_ID(adder, MASK_1, 0xFFFF);	write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1);	write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);	adder->x_clip_min = 0;	adder->x_clip_max = 1024;	adder->y_clip_min = 0;	adder->y_clip_max = 864;	/*	 * load DESTINATION origin and vectors  	 */	adder->fast_dest_dy = 0;	adder->slow_dest_dx = 0;	adder->error_1 = 0;	adder->error_2 = 0;	adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;	(void)wait_status(adder, RASTEROP_COMPLETE);	adder->destination_x = cursor[unit].x;	adder->fast_dest_dx = CHAR_WIDTH;	adder->destination_y = cursor[unit].y;	adder->slow_dest_dy = CHAR_HEIGHT;	/*	 * load SOURCE origin and vectors  	 */	if ((chr - ' ') > (CHARS - 1))  {		printf("Invalid character (x)%x in blitc\n",chr);		chr = ' ';	}	/*	 * X position is modulo the number of characters per line 	 */	adder->source_1_x = FONT_X + 	    (((chr - ' ') % (MAX_SCREEN_X/CHAR_WIDTH)) * CHAR_WIDTH);	/*	 * Point to either first or second row 	 */	adder->source_1_y = 2048 - 15 * 	    (((chr - ' ')/(MAX_SCREEN_X/CHAR_WIDTH)) + 1);	adder->source_1_dx = CHAR_WIDTH;	adder->source_1_dy = CHAR_HEIGHT;	write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);	adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;	/*	 * update console cursor coordinates 	 */	cursor[unit].x += CHAR_WIDTH;	if (nograph)		dga->x_cursor = TRANX(cursor[unit].x);	if (cursor[unit].x > (1024 - CHAR_WIDTH)) {		blitc(unit, '\r');		blitc(unit, '\n');	}} /* blitc */qdreset() { }/* *  INTERRUPT SERVICE ROUTINES *//* *  Service "DMA DONE" interrupt condition */qddint(qd)	register qd;{	register struct DMAreq_header *header;	register struct DMAreq *request;	register struct dga *dga;	struct adder *adder;	int cookie;			/* DMA adrs for QDSS */	(void)spl4(); 			/* allow interval timer in */	/*	* init pointers 	*/	header = DMAheader[qd]; 	    /* register for optimization */	dga = (struct dga *) qdmap[qd].dga;	adder = (struct adder *) qdmap[qd].adder;	/*	* if this interrupt flagged as bogus for interrupt flushing purposes.. 	*/	if (DMA_ISIGNORE(header)) {		DMA_CLRIGNORE(header);		return;	}	/*	* dump a DMA hardware error message if appropriate	*/	if (dga->csr & DMA_ERR) {		if (dga->csr & PARITY_ERR)		    printf("qd%d: qddint: DMA hardware parity fault.\n", qd);		if (dga->csr & BUS_ERR)		    printf("qd%d: qddint: DMA hardware bus error.\n", qd);	}	/*	* if this was a DMA from user space... 	*/	if (qdflags[qd].user_dma) {		qdflags[qd].user_dma = 0;		wakeup((caddr_t)&qdflags[qd].user_dma);		return;	}	/*	* if we're doing DMA request queue services, field the error condition 	*/	if (dga->csr & DMA_ERR) {		dga->csr &= ~0x0600;		/* halt DMA (reset fifo) */		dga->csr |= DMA_ERR;		/* clear error condition */		adder->command = CANCEL;	/* cancel adder activity */		DMA_SETERROR(header);	/* flag error in header status word */		DMA_CLRACTIVE(header);		header->DMAreq[header->oldest].DMAdone |= HARD_ERROR;		header->newest = header->oldest;		header->used = 0;		if (qdrsel[qd] && qdflags[qd].selmask & SEL_WRITE) {			selwakeup(qdrsel[qd], 0);			qdrsel[qd] = 0;			qdflags[qd].selmask &= ~SEL_WRITE;		}		if (dga->bytcnt_lo != 0) {			dga->bytcnt_lo = 0;			dga->bytcnt_hi = 0;			DMA_SETIGNORE(header);		}		return;	}	/*	* if the DMA request queue is now becoming non-full, 	* wakeup "select" client.	*/	if (DMA_ISFULL(header)) {		if (qdrsel[qd] && qdflags[qd].selmask & SEL_WRITE) {			selwakeup(qdrsel[qd], 0);			qdrsel[qd] = 0;			qdflags[qd].selmask &= ~SEL_WRITE;		}	}	header->DMAreq[header->oldest].DMAdone |= REQUEST_DONE;	QDlast_DMAtype = header->DMAreq[header->oldest].DMAtype;	/* check for unexpected interrupt */	if (DMA_ISEMPTY(header))	    return;	DMA_GETEND(header);	/* update request queue indices */	/*	* if no more DMA pending, wake up "select" client and exit 	*/	if (DMA_ISEMPTY(header)) {		if (qdrsel[qd] && qdflags[qd].selmask & SEL_WRITE) {			selwakeup(qdrsel[qd], 0);			qdrsel[qd] = 0;			qdflags[qd].selmask &= ~SEL_WRITE;		}		DMA_CLRACTIVE(header);  /* flag DMA done */		return;	}	/*	* initiate next DMA xfer  	*/	request = DMA_GETBEGIN(header);	if (request->DMAtype != QDlast_DMAtype) {		dga->csr &= ~0x0600;	  /* halt DMA (reset fifo) */		adder->command = CANCEL;  /* cancel adder activity */	}	switch (request->DMAtype) {	case DISPLIST:		if (request->DMAtype != QDlast_DMAtype) {			dga->csr |= DL_ENB;			dga->csr &= ~(BTOP_ENB | BYTE_DMA);		}		break;	case PTOB:		if (request->DMAtype != QDlast_DMAtype) {			if (request->DMAdone & BYTE_PACK)			    dga->csr |= (PTOB_ENB | BYTE_DMA);			else {				dga->csr |= PTOB_ENB;				dga->csr &= ~BYTE_DMA;			}		}		break;	case BTOP:		if (request->DMAtype != QDlast_DMAtype) {			if (request->DMAdone & BYTE_PACK) {				dga->csr &= ~DL_ENB;				dga->csr |= (BTOP_ENB | BYTE_DMA);			}			else {				dga->csr |= BTOP_ENB;				dga->csr &= ~(BYTE_DMA | DL_ENB);			}		}		break;	default:		printf("qd%d: qddint: illegal DMAtype parameter.\n", qd);		DMA_CLRACTIVE(header);	/* flag DMA done */		return;	}	if (request->DMAdone & COUNT_ZERO) {		dga->csr &= ~SET_DONE_FIFO;	} 	else if (request->DMAdone & FIFO_EMPTY) {		dga->csr |= SET_DONE_FIFO;	}	if (request->DMAdone & WORD_PACK)	    dga->csr &= ~BYTE_DMA;	else if (request->DMAdone & BYTE_PACK)	    dga->csr |= BYTE_DMA;	dga->csr |= DMA_IE;	QDlast_DMAtype = request->DMAtype;	cookie = ((int)request->bufp - (int)header) + (int)header->QBAreg;	dga->adrs_lo = (short) cookie;	dga->adrs_hi = (short) (cookie >> 16);	dga->bytcnt_lo = (short) request->length;	dga->bytcnt_hi = (short) (request->length >> 16);	return;}/* * ADDER interrupt service routine */qdaint(qd)	register qd;{	register struct adder *adder;	struct color_buf *cbuf;	int i;	register struct rgb *rgbp;	register short *red;	register short *green;	register short *blue;	(void)spl4(); 			/* allow interval timer in */	adder = (struct adder *) qdmap[qd].adder;	/*	* service the vertical blank interrupt (VSYNC bit) by loading 	* any pending color map load request  	*/	if (adder->status & VSYNC) {		adder->status &= ~VSYNC;	/* clear the interrupt */		cbuf = color_buf[qd];		if (cbuf->status & LOAD_COLOR_MAP) {			red = (short *) qdmap[qd].red;			green = (short *) qdmap[qd].green;			blue = (short *) qdmap[qd].blue;			for (i = cbuf->count, rgbp = cbuf->rgb;			     --i >= 0; rgbp++) {				red[rgbp->offset] = (short) rgbp->red;				green[rgbp->offset] = (short) rgbp->green;				blue[rgbp->offset] = (short) rgbp->blue;			}			cbuf->status &= ~LOAD_COLOR_MAP;		}	}	/*	* service the scroll interrupt (FRAME_SYNC bit) 	*/	if (adder->status & FRAME_SYNC) {		adder->status &= ~FRAME_SYNC;	/* clear the interrupt */		if (scroll[qd]->status & LOAD_REGS) {			for (i = 1000, adder->status = 0; i > 0 && 

⌨️ 快捷键说明

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