SRI-NOSC/dmr/cr.c

Compare this file to the similar file:
Show the results in this format:

#/*
Module Name:
	cr.c -- card reader driver for Unix

Installation:

Function:
	Provide the interface necessary to handle the CR-11 card reader.

Globals contained:
	cr11	control info and wait channel address

Routines contained:
	cropen	process-level open request
	crclose	process-level close request
	crread	process-level read request
	crint	interrupt handler

Modules referenced:
	param.h		miscellaneous parameters
	conf.h		configuration options
	user.h		defination of the user table
	m40.s		for getc and putc

Modules referencing:
	c.c and l.s

Compile time parameters and effects:
	CRPRI	Waiting priority for the card reader.  Should be positive.
		Since the card reader is a delayable device, this needn't
		be particularly high (i.e., a low number).
	CRLOWAT	The low water mark.  If the card reader has been stopped
		because the process code has not been taking the data, this
		is the point at which to restart it.
	CRHIWAT	The high water mark.  If the queued data exceeds this limit
		at a card boundry, the reader will be temporarily stopped.

Module History:
	Created 30Jan78 by Greg Noel, based upon the version from the
		Children's Museum, which didn't work on our system.
		(The original was Copyright 1974; reproduced by permission.)
*/
#include	"param.h"
#include	"conf.h"
#include	"user.h"

#define	CRPRI	10
#define	CRLOWAT	50
#define	CRHIWAT	160

#define	NLCHAR	0140	/* internal value used for end-of-line */
#define	EOFCHAR	07417	/* end-of-file character (not currently used) */

		/* the device registers */

struct {
	int crcsr;
	int crbuf1;
	int crbuf2;
};
#define	CRADDR	0177160

		/* values defined on the crcsr field */

#define     RDRENB	0000001
#define     EJECT	0000002
#define     IENABLE	0000100
#define     COLDONE	0000200
#define     READY	0000400
#define     BUSY	0001000
#define     ONLINE	0002000
#define     TIMERR	0004000
#define     RDCHECK	0010000
#define     PICKCHECK	0020000
#define     CARDDONE	0040000
#define     ERROR	0100000

		/* card reader status */

struct {
	int crstate;
	struct {
		int cc;
		int cf;
		int cl;
	} crin;
} cr11;

		/* values defined over the crstate field */

#define	CLOSED	0
#define	WAITING	1
#define	READING	2
#define	EOF	3

char asctab[]
{
	' ','1','2','3','4','5','6','7',
	'8',' ',':','#','@','`','=','"',
	'9','0','/','s','t','u','v','w',
	'x','y',' ',']',',','%','_','>',
	'?','z','-','j','k','l','m','n',
	'o','p','q',' ','!','$','*',')',
	';','\\','r','&','a','b','c','d',
	'e','f','g','h',' ','[','.','<',
	'(','+','^','i',' ',' ',' ',' '
};

cropen(dev,flag)
{
	extern lbolt;

	if (flag!=0 || cr11.crstate!=CLOSED) {
	err:	u.u_error = ENXIO;
		return;
	}
	while(CRADDR->crcsr & (ERROR|PICKCHECK|RDCHECK|TIMERR|READY|BUSY)) {
		CRADDR->crcsr = 0;
		sleep(&lbolt,CRPRI);
		if(cr11.crstate != CLOSED) goto err; /* somebody else got it */
	}
	CRADDR->crcsr = IENABLE|RDRENB;
	cr11.crstate = WAITING;
}

crclose(dev,flag)
{
	spl6();
	CRADDR->crcsr = 0;
	while (getc(&cr11.crin) >= 0);
	cr11.crstate = CLOSED;
	spl0();
}

crread()
{
	register int c;

	do {
		spl6();
		while((c = getc(&cr11.crin))<0) {
			if(cr11.crstate == EOF)
				goto out;
			if((CRADDR->crcsr & CARDDONE) && (cr11.crin.cc<CRHIWAT))
				CRADDR->crcsr =| IENABLE|RDRENB;
			sleep(&cr11.crin,CRPRI);
		}
		spl0();
	} while (passc(asciicon(c)) >= 0);

out:
	spl0();
}

crint()
{
	if (cr11.crstate == WAITING) {
		if(CRADDR->crcsr & ERROR) {
			CRADDR->crcsr = IENABLE|RDRENB;
			return;
		}
		cr11.crstate = READING;
	}
	if(cr11.crstate == READING) {
		if (CRADDR->crcsr & ERROR)
			/*
			   This code is not really smart enough.  The acutal
			   EOF condition is indicated by a simultaneous
			   PICKCHECK and CARDDONE; anything else is a real
			   error.  In the event of a real error we should
			   discard the current card image, wait for the
			   operator to fix it, and continue.  This is very
			   hard to do.....
			*/
			cr11.crstate = EOF;
		else {
			if ((CRADDR->crcsr&CARDDONE) == 0) {
				putc(CRADDR->crbuf2,&cr11.crin);
				return;
			} else {
				cr11.crstate = WAITING;
				if (cr11.crin.cc < CRHIWAT)
					CRADDR->crcsr = IENABLE|RDRENB;
			}
		}
		putc(NLCHAR,&cr11.crin);   /* card end or EOF -- insert CR */
		wakeup(&cr11.crin);
	}
}

asciicon(c)
{
	register c1, c2;

	c1 = c&0377;
	if (c1 == NLCHAR)
		return('\n');
	if (c1>=0200)
		c1 =- 040;
	c2 = c1;
	while ((c2 =- 040) >= 0)
		c1 =- 017;
	if(c1 > 0107)
		c1 = ' ';
	else c1 = asctab[c1];
	return(c1);
}