AUSAM/sys/dmr/unused/lp.c

#
/*
 *	copyright 1976 ian johnstone
 *
 *	-->	this line printer driver will handle printers
 *		in the best most efficient way.
 *	-->	no upper to lower case conversion.
 *	-->	recognize zero,blank suppression.
 *	-->	support infinite size pages.
 *	-->	support 013 as skip to channel four.
 */

#include "../defines.h"
#include "../param.h"
#include "../conf.h"
#include "../user.h"
#include "../proc.h"
#include "../buf.h"

#define	ienable	0100
#define	done	0200
#define	error	0100000

#define nlp	1	/* number of line printers */
#define	lppri	10
#define	maxcol	132
#define	open	01
#define	closin	02
#define  bmax	02	/* maximum number of buffers for a line printer */

int lpages 0;	/* pages printed since last boot */

struct lpdev {
	int lpsr;
	int lpbuf;
};
struct  { int lpuf;  };	/* dummy for lpint only */

struct lpst  {
	struct devtab dtab;	/* buffer pointer */
	struct lpdev *lpaddr;	/* device register address */
	int	flag;	/* control flags */
	int   ejline;   /* lines per page */
	int	mcc;
	int	ccc;	/* character count */
	int	mlc;	/* linecount */
#ifndef unsw_orig
	int	vtc;	/* vertical tab counter */
#endif
	int bfree;	/* number of buffers that are left to go */
	int	bc;	/* byte count (-ve) */
	char	*ba;	/* pointer of where up to */
	char	fc;	/* if non-zero it is char to be duplicated */
};
#ifndef unsw_orig
  struct lpst lp0 { 0,0,0,0,0,0,0177514,0,0,0,0,0,0,bmax,0,0,0 };
#endif
#ifdef unsw_orig
  struct lpst lp0 { 0,0,0,0,0,0177514,0,0,0,0,0,bmax,0,0,0 };
#endif

struct lpst *lp11[nlp] { &lp0, };

int lpflush 0;	/* set externally if buffer pool to be flushed !! */

lpopen(dev, flag)
{	register struct lpst *plp;

	plp = lp11[dev.d_minor];
	if( (dev.d_minor >= nlp) ||
	    (plp->flag & open)   ||
	    ( !flag )	         ||
	    ((plp->lpaddr)->lpsr < 0)	)  u.u_error = EIO;
	else {
	plp->flag = open;	plp->ejline = 60;
	(plp->lpaddr)->lpsr =| ienable;
	plp->ccc = plp->mlc = plp->mcc = 0;
	lpflush = 0;	/* reinit */
	}
}

lpclose(dev, flag)
{	register struct lpst *plp;

	plp = lp11[dev.d_minor];
	plp->flag = open|closin;
	while(plp->bfree != bmax) sleep(plp,lppri);
	(plp->lpaddr)->lpsr  =& ~ienable;
	if(plp->mcc | plp->mlc)  (plp->lpaddr)->lpbuf = 014;
	plp->flag=0;
}

lpwrite(dev)
{	register struct buf *bp;
	register struct lpst *plp;	int register n;

	plp= lp11[dev.d_minor];
	spl4();
 while(u.u_count && !u.u_error) {
	while(!plp->bfree)	sleep(plp,lppri);
	if( lpflush ) {
		u.u_error = EIO;
		break;
	}
	plp->bfree--;
	bp = getblk(NODEV); bp->av_forw = 0;
	spl4();
	if( (n=u.u_count) > 512 ) n=512;
	bp->b_wcount = -n;  iomove(bp,0,n,B_WRITE);
	if(!plp->dtab.d_actf) {
		plp->dtab.d_actf = plp->dtab.d_actl = bp;
		plp->ba = bp->b_addr;
		plp->bc = bp->b_wcount;
		lpint(dev);
	} else {
		(plp->dtab.d_actl)->av_forw = bp;
		plp->dtab.d_actl = bp;
	}
     }
	spl0();
}

lpint(dev)
{	register struct lpst *plp;
	struct buf *bp; register int *lpa;
	register  c1;

	if( !(bp=(plp= lp11[dev.d_minor])->dtab.d_actf) ) goto fin;
	if(lpflush) {
		do {
			lpa = bp->av_forw;
			brelse(bp);
			plp->bfree++;
		} while( bp = lpa );
		plp->dtab.d_actf = 0;
		wakeup(plp);
		goto fin;
	}
	if((plp->lpaddr)->lpsr&error) { timeout(lpint,dev,120); return; }
	lpa = &(plp->lpaddr)->lpbuf;
#ifndef unsw_orig
	if(plp->vtc) {
		lpa->lpuf = '\n';
		plp->vtc--;
		return;
	}
#endif
loop: while( ((plp->lpaddr)->lpsr&done) && (plp->bc++ <0) ) {
	c1 = (*plp->ba++)&0377;
	if( plp->fc ) {
		plp->ccc =+(--c1);
		if(plp->fc=='0') {
			if(plp->ccc>maxcol) c1=- plp->ccc-maxcol;
			while(c1-- > 0) lpa->lpuf = '0';
		}
		plp->fc=0;
		goto loop;
	}
	switch( c1 ) {
	case '{':
			c1 = '(';	goto esc;
	case '}':
			c1 = ')';	goto esc;
	case '`':
			c1 = '\'';	goto esc;
	case '|':
			c1 = '!';	goto esc;
	case '~':
			c1 = '^';
	esc:
			while(plp->ccc > plp->mcc){
				lpa->lpuf = ' ';
				plp->mcc++;
			}
			lpa->lpuf = c1;
			*(--plp->ba) = '-'; --plp->bc;
			lpa->lpuf = '\r';
			plp->mcc=0;
	case 0:		break;
	case '\t':	plp->ccc = (plp->ccc+8) & ~7; break;
	case 0377:	plp->fc = c1 = ' '; goto dflt;
	case 0376:	plp->fc = c1 = '0'; goto dflt;
	case 0375:	plp->ejline = 32767;
			break;
	case 013:
#ifndef unsw_orig
			plp->vtc = 61-plp->mlc;
			plp->mlc = -3;
			plp->ccc=0; plp->mcc=1;
			lpa->lpuf = '\n';
			return;
#endif
#ifdef unsw_orig
			break;
			plp->mlc=plp->ccc=0; plp->mcc=1;
			break;
#endif
	case 014:
	case '\n':
			if(plp->mlc||plp->mcc) {
				plp->mcc = 0;
				plp->mlc++;
				if(plp->mlc >= plp->ejline ) c1 = 014;
				lpa->lpuf=c1;
				if(c1 == 014) { 
				    	plp->mlc=0; lpages++; 
				}
			}
	case '\r':
			plp->ccc = 0;
			break;
	case 010:
			if(plp->ccc > 0)
				plp->ccc--;
			break;
	case ' ':
			plp->ccc++;
			break;
	default:
	dflt:
			if(plp->ccc < plp->mcc) {
				lpa->lpuf= '\r';
				plp->mcc = plp->fc = 0;
				--plp->ba; --plp->bc;
				break;
			}
			if(plp->ccc < maxcol) {
				while(plp->ccc > plp->mcc) {
					lpa->lpuf= ' ';
					plp->mcc++;
				}
				lpa->lpuf= c1;
				plp->mcc++;
			}
			plp->ccc++;
	}
      }
	if(plp->bc>=0) {
		plp->dtab.d_actf = (bp = plp->dtab.d_actf)->av_forw;
		brelse(bp);
		if(!(plp->bfree++)) wakeup(plp);
		if(bp=plp->dtab.d_actf) {
			plp->ba = bp->b_addr;
			plp->bc = bp->b_wcount;
			goto loop;
		}
	fin:
	    if( ((plp->lpaddr)->lpsr&done)&&(plp->flag&closin) )wakeup(plp);
	}
}
#ifdef	POWER_FAIL

lppowf()
{
	register struct lpst *plp;
	register i;

	for( i = 0 ; i < nlp ; i++ ) {
		plp = lp11[i];
		if( plp->flag&open ) (plp->lpaddr)->lpsr =| ienable;
	}
}
#endif	POWER_FAIL