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: /* --------------------------- */