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