home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / sys / dmr / tc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-07-18  |  2.7 KB  |  172 lines

  1. #
  2. /*
  3.  */
  4.  
  5. /*
  6.  * TC-11 DECtape driver
  7.  */
  8.  
  9. #include "../param.h"
  10. #include "../conf.h"
  11. #include "../buf.h"
  12. #include "../user.h"
  13.  
  14. struct {
  15.     int    tccsr;
  16.     int    tccm;
  17.     int    tcwc;
  18.     int    tcba;
  19.     int    tcdt;
  20. };
  21.  
  22. struct    devtab    tctab;
  23. char    tcper[8];
  24.  
  25. #define    TCADDR    0177340
  26. #define    NTCBLK    578
  27.  
  28. #define    TAPERR    0100000
  29. #define    TREV    04000
  30. #define    READY    0200
  31. #define    IENABLE    0100
  32. #define    UPS    0200
  33. #define    ENDZ    0100000
  34. #define    BLKM    02000
  35. #define    ILGOP    010000
  36. #define    SELERR    04000
  37.  
  38. #define    SAT    0
  39. #define    RNUM    02
  40. #define    RDATA    04
  41. #define    SST    010
  42. #define    WDATA    014
  43. #define    GO    01
  44.  
  45. #define    SFORW    1
  46. #define    SREV    2
  47. #define    SIO    3
  48.  
  49. tcclose(dev)
  50. {
  51.     bflush(dev);
  52.     tcper[dev&07] = 0;
  53. }
  54.  
  55. tcstrategy(abp)
  56. struct buf *abp;
  57. {
  58.     register struct buf *bp;
  59.  
  60.     bp = abp;
  61.     if(bp->b_flags&B_PHYS)
  62.         mapalloc(bp);
  63.     if(bp->b_blkno >= NTCBLK || tcper[bp->b_dev&07]) {
  64.         bp->b_flags =| B_ERROR;
  65.         iodone(bp);
  66.         return;
  67.     }
  68.     bp->av_forw = 0;
  69.     spl6();
  70.     if (tctab.d_actf==0)
  71.         tctab.d_actf = bp;
  72.     else
  73.         tctab.d_actl->av_forw = bp;
  74.     tctab.d_actl = bp;
  75.     if (tctab.d_active==0)
  76.         tcstart();
  77.     spl0();
  78. }
  79.  
  80. tcstart()
  81. {
  82.     register struct buf *bp;
  83.     register int *tccmp, com;
  84.  
  85. loop:
  86.     tccmp = &TCADDR->tccm;
  87.     if ((bp = tctab.d_actf) == 0)
  88.         return;
  89.     if(tcper[bp->b_dev&07]) {
  90.         if((tctab.d_actf = bp->av_forw) == 0)
  91.             (*tccmp).lobyte = SAT|GO;
  92.         bp->b_flags =| B_ERROR;
  93.         iodone(bp);
  94.         goto loop;
  95.     }
  96.     if (((*tccmp).hibyte&07) != bp->b_dev.d_minor)
  97.         (*tccmp).lobyte = SAT|GO;
  98.     tctab.d_errcnt = 20;
  99.     tctab.d_active = SFORW;
  100.     com = (bp->b_dev.d_minor<<8) | IENABLE|RNUM|GO;
  101.     if ((TCADDR->tccsr & UPS) == 0) {
  102.         com =| TREV;
  103.         tctab.d_active = SREV;
  104.     }
  105.     *tccmp = com;
  106. }
  107.  
  108. tcintr()
  109. {
  110.     register struct buf *bp;
  111.     register int *tccmp;
  112.     register int *tcdtp;
  113.  
  114.     tccmp = &TCADDR->tccm;
  115.     tcdtp = &TCADDR->tccsr;
  116.     bp = tctab.d_actf;
  117.     if (*tccmp&TAPERR) {
  118.         if((*tcdtp&(ENDZ|BLKM)) == 0)
  119.             deverror(bp, *tcdtp, 0);
  120.         if(*tcdtp & (ILGOP|SELERR)) {
  121.             tcper[bp->b_dev&07]++;
  122.             tctab.d_errcnt = 0;
  123.         }
  124.         *tccmp =& ~TAPERR;
  125.         if (--tctab.d_errcnt  <= 0) {
  126.             bp->b_flags =| B_ERROR;
  127.             goto done;
  128.         }
  129.         if (*tccmp&TREV) {
  130.         setforw:
  131.             tctab.d_active = SFORW;
  132.             *tccmp =& ~TREV;
  133.         } else {
  134.         setback:
  135.             tctab.d_active = SREV;
  136.             *tccmp =| TREV;
  137.         }
  138.         (*tccmp).lobyte = IENABLE|RNUM|GO;
  139.         return;
  140.     }
  141.     tcdtp = &TCADDR->tcdt;
  142.     switch (tctab.d_active) {
  143.  
  144.     case SIO:
  145.     done:
  146.         tctab.d_active = 0;
  147.         if (tctab.d_actf = bp->av_forw)
  148.             tcstart();
  149.         else
  150.             TCADDR->tccm.lobyte = SAT|GO;
  151.         iodone(bp);
  152.         return;
  153.  
  154.     case SFORW:
  155.         if (*tcdtp > bp->b_blkno)
  156.             goto setback;
  157.         if (*tcdtp < bp->b_blkno)
  158.             goto setforw;
  159.         *--tcdtp = bp->b_addr;        /* core address */
  160.         *--tcdtp = bp->b_wcount;
  161.         tccmp->lobyte = ((bp->b_xmem & 03) << 4) | IENABLE|GO
  162.             | (bp->b_flags&B_READ?RDATA:WDATA);
  163.         tctab.d_active = SIO;
  164.         return;
  165.  
  166.     case SREV:
  167.         if (*tcdtp+3 > bp->b_blkno)
  168.             goto setback;
  169.         goto setforw;
  170.     }
  171. }
  172.