1: /* 2: * SCCS id @(#)cr.c 2.1 (Berkeley) 8/5/83 3: */ 4: 5: /* 6: Module Name: 7: cr.c -- card reader driver for Unix 8: 9: Installation: 10: 11: Function: 12: Provide the interface necessary to handle the CR-11 card reader. 13: 14: Globals contained: 15: cr11 control info and wait channel address 16: 17: Routines contained: 18: cropen process-level open request 19: crclose process-level close request 20: crread process-level read request 21: crint interrupt handler 22: 23: Modules referenced: 24: param.h miscellaneous parameters 25: conf.h configuration options 26: user.h definition of the user table 27: 28: Modules referencing: 29: c.c and l.s 30: 31: Compile time parameters and effects: 32: CRPRI Waiting priority for the card reader. Should be positive. 33: Since the card reader is a delayable device, this needn't 34: be particularly high (i.e., a low number). 35: CRLOWAT The low water mark. If the card reader has been stopped 36: because the process code has not been taking the data, this 37: is the point at which to restart it. 38: CRHIWAT The high water mark. If the queued data exceeds this limit 39: at a card boundry, the reader will be temporarily stopped. 40: 41: Module History: 42: Created 30Jan78 by Greg Noel, based upon the version from the 43: Children's Museum, which didn't work on our system (the original 44: was Copyright 1974; reproduced by permission). 45: */ 46: /*! Rehacked for v7 by Bill Jolitz 8/79 */ 47: #include "param.h" 48: #include "cr.h" 49: #if NCR > 0 50: #include <sys/dir.h> 51: #include <sys/conf.h> 52: #include <sys/user.h> 53: #include <sys/crreg.h> 54: 55: #define CRPRI (PZERO+10) 56: #define CRLOWAT 50 57: #define CRHIWAT 160 58: 59: #define NLCHAR 0140 /* internal value used for end-of-line */ 60: #define EOFCHAR 07417 /* end-of-file character (not currently used) */ 61: 62: /* card reader status */ 63: struct { 64: int crstate; /* see below */ 65: struct { 66: int cc; 67: int cf; 68: int cl; 69: } crin; 70: } cr11; 71: /* bits in crstate */ 72: #define CLOSED 0 73: #define WAITING 1 74: #define READING 2 75: #define EOF 3 76: 77: int nospl = { 0 }; 78: extern struct crdevice *CRADDR; 79: 80: char asctab[] 81: { 82: ' ', '1', '2', '3', '4', '5', '6', '7', 83: '8', ' ', ':', '#', '@', '`', '=', '"', 84: '9', '0', '/', 's', 't', 'u', 'v', 'w', 85: 'x', 'y', ' ', ']', ',', '%', '_', '>', 86: '?', 'z', '-', 'j', 'k', 'l', 'm', 'n', 87: 'o', 'p', 'q', ' ', '!', '$', '*', ')', 88: ';', '\\', 'r', '&', 'a', 'b', 'c', 'd', 89: 'e', 'f', 'g', 'h', ' ', '[', '.', '<', 90: '(', '+', '^', 'i', ' ', ' ', ' ', ' ' 91: }; 92: #define BADCHAR '~' /* was blank */ 93: 94: /*ARGSUSED*/ 95: cropen(dev, flag) 96: dev_t dev; 97: { 98: extern lbolt; 99: 100: if (flag!=0 || cr11.crstate!=CLOSED) { 101: err: 102: u.u_error = ENXIO; 103: return; 104: } 105: while(CRADDR->crcs & (CR_HARDERR|CR_RRS|CR_BUSY)) { 106: CRADDR->crcs = 0; 107: sleep(&lbolt, CRPRI); 108: if(cr11.crstate != CLOSED) 109: goto err; /* somebody else got it */ 110: } 111: CRADDR->crcs = CR_IE|CR_READ; 112: cr11.crstate = WAITING; 113: } 114: 115: /*ARGSUSED*/ 116: crclose(dev, flag) 117: dev_t dev; 118: { 119: if(!nospl) 120: (void) _spl6(); 121: CRADDR->crcs = 0; 122: while (getc(&cr11.crin) >= 0) 123: ; 124: cr11.crstate = CLOSED; 125: (void) _spl0(); 126: } 127: 128: crread() 129: { 130: register int c; 131: 132: do { 133: if(!nospl) 134: (void) _spl6(); 135: while((c = getc(&cr11.crin))<0) { 136: if(cr11.crstate == EOF) 137: goto out; 138: if((CRADDR->crcs & CR_CARDDONE) && (cr11.crin.cc<CRHIWAT)) 139: CRADDR->crcs |= CR_IE|CR_READ; 140: sleep(&cr11.crin,CRPRI); 141: } 142: (void) _spl0(); 143: } while (passc(asciicon(c)) >= 0); 144: 145: out: 146: (void) _spl0(); 147: } 148: 149: crint() 150: { 151: if (cr11.crstate == WAITING) { 152: if(CRADDR->crcs & CR_ERR) { 153: CRADDR->crcs = CR_IE|CR_READ; 154: return; 155: } 156: cr11.crstate = READING; 157: } 158: if(cr11.crstate == READING) { 159: if (CRADDR->crcs & CR_ERR) 160: /* 161: This code is not really smart enough. The actual 162: EOF condition is indicated by a simultaneous 163: CR_HCHK and CR_CARDDONE; anything else is a real 164: error. In the event of a real error we should 165: discard the current card image, wait for the 166: operator to fix it, and continue. This is very 167: hard to do..... 168: */ 169: cr11.crstate = EOF; 170: else 171: { 172: if ((CRADDR->crcs&CR_CARDDONE) == 0) { 173: putc(CRADDR->crb2,&cr11.crin); 174: return; 175: } else 176: { 177: cr11.crstate = WAITING; 178: if (cr11.crin.cc < CRHIWAT) 179: CRADDR->crcs = CR_IE|CR_READ; 180: } 181: } 182: putc(NLCHAR,&cr11.crin); /* card end or EOF -- insert CR */ 183: wakeup(&cr11.crin); 184: } 185: } 186: 187: asciicon(c) 188: { 189: register c1, c2; 190: 191: c1 = c&0377; 192: if (c1 == NLCHAR) 193: return('\n'); 194: if (c1>=0200) 195: c1 -= 040; 196: c2 = c1; 197: while ((c2 -= 040) >= 0) 198: c1 -= 017; 199: if(c1 > 0107) 200: c1 = BADCHAR; 201: else 202: c1 = asctab[c1]; 203: return(c1); 204: } 205: #endif NCR