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