8600: # 8601: /* PC-11 Paper tape reader/punch driver */ 8602: 8603: #include "../param.h" 8604: #include "../conf.h" 8605: #include "../user.h" 8606: 8607: #define PCADDR 0177550 8608: 8609: #define CLOSED 0 8610: #define WAITING 1 8611: #define READING 2 8612: #define EOF 3 8613: 8614: #define RDRENB 01 8615: #define IENABLE 0100 8616: #define DONE 0200 8617: #define BUSY 04000 8618: #define ERROR 0100000 8619: 8620: #define PCIPRI 30 8621: #define PCOPRI 40 8622: #define PCOLWAT 50 8623: #define PCOHWAT 100 8624: #define PCIHWAT 250 8625: 8626: struct { 8627: int pcrcsr; 8628: int pcrbuf; 8629: int pcpcsr; 8630: int pcpbuf; 8631: }; 8632: /* --------------------------- */ 8633: 8634: struct clist { 8635: int cc; 8636: int cf; 8637: int cl; 8638: }; 8639: /* --------------------------- */ 8640: 8641: struct pc11 { 8642: int pcstate; 8643: struct clist pcin; 8644: struct clist pcout; 8645: } pc11; 8646: /* --------------------------- */ 8647: 8648: pcopen(dev, flag) 8649: { 8650: extern lbolt; 8651: 8652: if (flag==0) { 8653: if (pc11.pcstate!=CLOSED) { 8654: u.u_error = ENXIO; 8655: return; 8656: } 8657: pc11.pcstate = WAITING; 8658: while(pc11.pcstate==WAITING) { 8659: PCADDR->pcrcsr = IENABLE|RDRENB; 8660: sleep(&lbolt, PCIPRI); 8661: } 8662: } else { 8663: PCADDR->pcpcsr =| IENABLE; 8664: pcleader(); 8665: } 8666: } 8667: /* --------------------------- */ 8668: 8669: pcclose(dev, flag) 8670: { 8671: if (flag==0) { 8672: spl4(); 8673: while (getc(&pc11.pcin) >= 0); 8674: PCADDR->pcrcsr = 0; 8675: pc11.pcstate = CLOSED; 8676: spl0(); 8677: } else 8678: pcleader(); 8679: } 8680: /* --------------------------- */ 8681: 8682: pcread() 8683: { 8684: register int c; 8685: 8686: spl4(); 8687: do { 8688: while ((c = getc(&pc11.pcin)) < 0) { 8689: if (pc11.pcstate==EOF) 8690: goto out; 8691: if ((PCADDR->pcrcsr&(ERROR|BUSY|DONE))==0) 8692: PCADDR->pcrcsr =| IENABLE|RDRENB; 8693: sleep(&pc11.pcin, PCIPRI); 8694: } 8695: } while (passc(c)>=0); 8696: out: 8697: spl0(); 8698: } 8699: /* --------------------------- */ 8700: 8701: pcwrite() 8702: { 8703: register int c; 8704: 8705: while ((c=cpass())>=0) 8706: pcoutput(c); 8707: } 8708: /* --------------------------- */ 8709: 8710: pcstart() 8711: { 8712: register int c; 8713: 8714: if (PCADDR->pcpcsr&DONE && (c = getc(&pc11.pcout)) >= 0) 8715: PCADDR->pcpbuf = c; 8716: } 8717: /* --------------------------- */ 8718: 8719: pcrint() 8720: { 8721: if (pc11.pcstate==WAITING) { 8722: if (PCADDR->pcrcsr&ERROR) 8723: return; 8724: pc11.pcstate = READING; 8725: } 8726: if (pc11.pcstate==READING) { 8727: if (PCADDR->pcrcsr&ERROR) 8728: pc11.pcstate = EOF; 8729: else { 8730: putc(PCADDR->pcrbuf, &pc11.pcin); 8731: if (pc11.pcin.cc < PCIHWAT) 8732: PCADDR->pcrcsr =| IENABLE|RDRENB; 8733: } 8734: wakeup(&pc11.pcin); 8735: } 8736: } 8737: /* --------------------------- */ 8738: 8739: pcpint() 8740: { 8741: 8742: pcstart(); 8743: if (pc11.pcout.cc <= PCOLWAT) 8744: wakeup(&pc11.pcout); 8745: } 8746: /* --------------------------- */ 8747: 8748: pcoutput(c) 8749: { 8750: if (PCADDR->pcpcsr&ERROR) { 8751: u.u_error = EIO; 8752: return; 8753: } 8754: if (pc11.pcout.cc >= PCOHWAT) 8755: sleep(&pc11.pcout, PCOPRI); 8756: putc(c, &pc11.pcout); 8757: spl4(); 8758: pcstart(); 8759: spl0(); 8760: } 8761: /* --------------------------- */ 8762: 8763: pcleader() 8764: { 8765: register int i; 8766: 8767: i = 100; 8768: do 8769: pcoutput(0); 8770: while (--i); 8771: } 8772: /* --------------------------- */