1: # 2: /* 3: */ 4: 5: /* 6: * PC-11 Paper tape reader/punch driver 7: */ 8: 9: #include "../param.h" 10: #include "../conf.h" 11: #include "../user.h" 12: 13: #define PCADDR 0177550 14: 15: #define CLOSED 0 16: #define WAITING 1 17: #define READING 2 18: #define EOF 3 19: 20: #define RDRENB 01 21: #define IENABLE 0100 22: #define DONE 0200 23: #define BUSY 04000 24: #define ERROR 0100000 25: 26: #define PCIPRI 30 27: #define PCOPRI 40 28: #define PCOLWAT 50 29: #define PCOHWAT 100 30: #define PCIHWAT 250 31: 32: struct { 33: int pcrcsr; 34: int pcrbuf; 35: int pcpcsr; 36: int pcpbuf; 37: }; 38: 39: struct clist { 40: int cc; 41: int cf; 42: int cl; 43: }; 44: 45: struct pc11 { 46: int pcstate; 47: struct clist pcin; 48: struct clist pcout; 49: } pc11; 50: 51: pcopen(dev, flag) 52: { 53: extern lbolt; 54: 55: if (flag==0) { 56: if (pc11.pcstate!=CLOSED) { 57: u.u_error = ENXIO; 58: return; 59: } 60: pc11.pcstate = WAITING; 61: while(pc11.pcstate==WAITING) { 62: PCADDR->pcrcsr = IENABLE|RDRENB; 63: sleep(&lbolt, PCIPRI); 64: } 65: } else { 66: PCADDR->pcpcsr =| IENABLE; 67: pcleader(); 68: } 69: } 70: 71: pcclose(dev, flag) 72: { 73: if (flag==0) { 74: spl4(); 75: while (getc(&pc11.pcin) >= 0); 76: PCADDR->pcrcsr = 0; 77: pc11.pcstate = CLOSED; 78: spl0(); 79: } else 80: pcleader(); 81: } 82: 83: pcread() 84: { 85: register int c; 86: 87: spl4(); 88: do { 89: while ((c = getc(&pc11.pcin)) < 0) { 90: if (pc11.pcstate==EOF) 91: goto out; 92: if ((PCADDR->pcrcsr&(ERROR|BUSY|DONE))==0) 93: PCADDR->pcrcsr =| IENABLE|RDRENB; 94: sleep(&pc11.pcin, PCIPRI); 95: } 96: } while (passc(c)>=0); 97: out: 98: spl0(); 99: } 100: 101: pcwrite() 102: { 103: register int c; 104: 105: while ((c=cpass())>=0) 106: pcoutput(c); 107: } 108: 109: pcstart() 110: { 111: register int c; 112: 113: if (PCADDR->pcpcsr&DONE && (c = getc(&pc11.pcout)) >= 0) 114: PCADDR->pcpbuf = c; 115: } 116: 117: pcrint() 118: { 119: if (pc11.pcstate==WAITING) { 120: if (PCADDR->pcrcsr&ERROR) 121: return; 122: pc11.pcstate = READING; 123: } 124: if (pc11.pcstate==READING) { 125: if (PCADDR->pcrcsr&ERROR) 126: pc11.pcstate = EOF; 127: else { 128: putc(PCADDR->pcrbuf, &pc11.pcin); 129: if (pc11.pcin.cc < PCIHWAT) 130: PCADDR->pcrcsr =| IENABLE|RDRENB; 131: } 132: wakeup(&pc11.pcin); 133: } 134: } 135: 136: pcpint() 137: { 138: 139: pcstart(); 140: if (pc11.pcout.cc <= PCOLWAT) 141: wakeup(&pc11.pcout); 142: } 143: 144: pcoutput(c) 145: { 146: if (PCADDR->pcpcsr&ERROR) { 147: u.u_error = EIO; 148: return; 149: } 150: if (pc11.pcout.cc >= PCOHWAT) 151: sleep(&pc11.pcout, PCOPRI); 152: putc(c, &pc11.pcout); 153: spl4(); 154: pcstart(); 155: spl0(); 156: } 157: 158: pcleader() 159: { 160: register int i; 161: 162: i = 100; 163: do 164: pcoutput(0); 165: while (--i); 166: }