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

📄 qd.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
	int QBAreg;	int bytcnt;	int s;	int unit;	int cookie;	int i,j,k;	unit = (minor(bp->b_dev) >> 2) & 0x07;/*-----------------* init pointers */	if ((QBAreg = ubasetup(0, bp, 0)) == 0) {	    mprintf("\nqd%d: qd_strategy: QBA setup error", 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 *//*********************************************************************	qdstart()... startup output to the console screen***********************************************************************	calling convention:**		qdstart(tp);*		struct tty *tp; 	;pointer to tty structure*********/qdstart(tp)register struct tty *tp;{	register int which_unit, unit, c;	register struct tty *tp0;	int s;	int curs_on;	struct dga *dga;	unit = minor(tp->t_dev);	tp0 = &qd_tty[(unit & 0x0FC)+1];	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, if the alternate console device* is open direct chars there.  Drop input from anything but the console* device on the floor.	*//* TANDEM is set on the second subchannel for flow control. */	while ( tp->t_outq.c_cc ) {	    if (unit == 0) {		/* console device */		if (tp0->t_state & TS_ISOPEN) {		    if (tp0->t_state & TS_TBLOCK)			goto out;		    c = getc(&tp->t_outq);		    (*linesw[tp0->t_line].l_rint)(c, tp0);		} else {		    c = getc(&tp->t_outq);		    blitc(which_unit, (char)(c & 0xFF));		}	    } else if (unit == 1) {	/* qconsole, do flow control */		    c = getc(&tp->t_outq);		    if ((tp0->t_state&TS_TBLOCK) == 0) {			tp = &qd_tty[0];			unit = minor(tp->t_dev);			unit &= 0x03;			continue;		    } else			goto out;	    } else		c = getc(&tp->t_outq);	}/*--------------------------------------------------------* If there are sleepers, and output has drained below low* water mark, wake up the sleepers. */	if ( tp->t_outq.c_cc <= TTLOWAT(tp) ) {		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 *//*********************************************************************	qdstop()... stop the tty********************************************************************/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);}/*********************************************************************	blitc()... output a character to the QDSS screen***********************************************************************	calling convention:**		blitc(chr);*		char chr;		;character to be displayed*********/blitc(unit, chr)int unit;unsigned char chr;{	register struct adder *adder;	register struct dga *dga;	register int i;	short x;	unsigned char savechar;/*---------------* init stuff  */	adder = (struct adder *) qdmap[unit].adder;	dga = (struct dga *) qdmap[unit].dga;/*---------------------------* non display character?  */	chr &= 0xFF;	switch (chr) {	    case '\r':			/* return char */		cursor[unit].x = 0;	        if (!(qdflags[unit].inuse & GRAPHIC_DEV))		    dga->x_cursor = TRANX(cursor[unit].x);		return(0);	    case '\t':			/* tab char */		for (i = 8 - ((cursor[unit].x >> 3) & 0x07); i > 0; --i) {		    blitc(unit, ' ');		}		return(0);	    case '\n':			/* line feed char */		if ((cursor[unit].y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) {		    if (qdflags[unit].inuse & GRAPHIC_DEV) {			cursor[unit].y = 0;		    } else {			cursor[unit].y -= CHAR_HEIGHT;			scroll_up(adder);		    }		}	        if (!(qdflags[unit].inuse & GRAPHIC_DEV))		    dga->y_cursor = TRANY(cursor[unit].y);		return(0);	    case '\b':			/* backspace char */		if (cursor[unit].x > 0) {		    cursor[unit].x -= CHAR_WIDTH;		    blitc(unit, ' ');		    cursor[unit].x -= CHAR_WIDTH;	            if (!(qdflags[unit].inuse & GRAPHIC_DEV))		        dga->x_cursor = TRANX(cursor[unit].x);		}		return(0);	    default:		/*----------------------------------------------------------		 * Weed out unprintable characters.  Printable characters fall		 * between space (0x20) and tilde (0x7E).  For 8-bit support		 * another range of printable characters are those between		 * 0xA1 and 0xFD. */		if ((chr < ' ') || (chr > 0xFD) || (chr < 0xA1 && chr > '~'))		    return(0);	}/*------------------------------------------* 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;	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 > '~') {		savechar = chr;		chr -= 34; /* These are to skip the (32) 8-bit control chars. 			      as well as DEL and 0xA0 which aren't printable */	}	if ((chr - ' ') > (CHARS - 1))  {		mprintf("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 (!(qdflags[unit].inuse & GRAPHIC_DEV))	    dga->x_cursor = TRANX(cursor[unit].x);	if (cursor[unit].x > (1024 - CHAR_WIDTH)) {	    blitc(unit, '\r');	    blitc(unit, '\n');	}} /* blitc */qdreset(){}qd_init(){}/**********************************************************************************************************************************************************************************************************	INTERRUPT SERVICE ROUTINES START HERE:*********************************************************************************************************************************************************************************************************//*******************************************************************	qddint()... service "DMA DONE" interrupt condition******************************************************************/qddint(qd)int qd;{	register struct DMAreq_header *header;	register struct DMAreq *request;	register struct dga *dga;	struct adder *adder;	int cookie;			/* DMA adrs for QDSS */	int i;	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)		mprintf("\nqd%d: qddint: DMA hardware parity fault.", qd);	    if (dga->csr & BUS_ERR)		mprintf("\nqd%d: qddint: DMA hardware bus error.", 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 (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) {		selwakeup(rsel[qd], 0);		rsel[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 (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) {		selwakeup(rsel[qd], 0);		rsel[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 (rsel[qd] && qdflags[qd].selmask & SEL_WRITE) {		selwakeup(rsel[qd], 0);		rsel[qd] = 0;		qdflags[qd].selmask &= ~SEL_WRITE;	    }	    DMA_CLRACTIVE(header);  /* fla

⌨️ 快捷键说明

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