pc.c

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 /* ------------------------ */ 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799