home *** CD-ROM | disk | FTP | other *** search
- #
- /*
- */
-
- /*
- * TC-11 DECtape driver
- */
-
- #include "../param.h"
- #include "../conf.h"
- #include "../buf.h"
- #include "../user.h"
-
- struct {
- int tccsr;
- int tccm;
- int tcwc;
- int tcba;
- int tcdt;
- };
-
- struct devtab tctab;
- char tcper[8];
-
- #define TCADDR 0177340
- #define NTCBLK 578
-
- #define TAPERR 0100000
- #define TREV 04000
- #define READY 0200
- #define IENABLE 0100
- #define UPS 0200
- #define ENDZ 0100000
- #define BLKM 02000
- #define ILGOP 010000
- #define SELERR 04000
-
- #define SAT 0
- #define RNUM 02
- #define RDATA 04
- #define SST 010
- #define WDATA 014
- #define GO 01
-
- #define SFORW 1
- #define SREV 2
- #define SIO 3
-
- tcclose(dev)
- {
- bflush(dev);
- tcper[dev&07] = 0;
- }
-
- tcstrategy(abp)
- struct buf *abp;
- {
- register struct buf *bp;
-
- bp = abp;
- if(bp->b_flags&B_PHYS)
- mapalloc(bp);
- if(bp->b_blkno >= NTCBLK || tcper[bp->b_dev&07]) {
- bp->b_flags =| B_ERROR;
- iodone(bp);
- return;
- }
- bp->av_forw = 0;
- spl6();
- if (tctab.d_actf==0)
- tctab.d_actf = bp;
- else
- tctab.d_actl->av_forw = bp;
- tctab.d_actl = bp;
- if (tctab.d_active==0)
- tcstart();
- spl0();
- }
-
- tcstart()
- {
- register struct buf *bp;
- register int *tccmp, com;
-
- loop:
- tccmp = &TCADDR->tccm;
- if ((bp = tctab.d_actf) == 0)
- return;
- if(tcper[bp->b_dev&07]) {
- if((tctab.d_actf = bp->av_forw) == 0)
- (*tccmp).lobyte = SAT|GO;
- bp->b_flags =| B_ERROR;
- iodone(bp);
- goto loop;
- }
- if (((*tccmp).hibyte&07) != bp->b_dev.d_minor)
- (*tccmp).lobyte = SAT|GO;
- tctab.d_errcnt = 20;
- tctab.d_active = SFORW;
- com = (bp->b_dev.d_minor<<8) | IENABLE|RNUM|GO;
- if ((TCADDR->tccsr & UPS) == 0) {
- com =| TREV;
- tctab.d_active = SREV;
- }
- *tccmp = com;
- }
-
- tcintr()
- {
- register struct buf *bp;
- register int *tccmp;
- register int *tcdtp;
-
- tccmp = &TCADDR->tccm;
- tcdtp = &TCADDR->tccsr;
- bp = tctab.d_actf;
- if (*tccmp&TAPERR) {
- if((*tcdtp&(ENDZ|BLKM)) == 0)
- deverror(bp, *tcdtp, 0);
- if(*tcdtp & (ILGOP|SELERR)) {
- tcper[bp->b_dev&07]++;
- tctab.d_errcnt = 0;
- }
- *tccmp =& ~TAPERR;
- if (--tctab.d_errcnt <= 0) {
- bp->b_flags =| B_ERROR;
- goto done;
- }
- if (*tccmp&TREV) {
- setforw:
- tctab.d_active = SFORW;
- *tccmp =& ~TREV;
- } else {
- setback:
- tctab.d_active = SREV;
- *tccmp =| TREV;
- }
- (*tccmp).lobyte = IENABLE|RNUM|GO;
- return;
- }
- tcdtp = &TCADDR->tcdt;
- switch (tctab.d_active) {
-
- case SIO:
- done:
- tctab.d_active = 0;
- if (tctab.d_actf = bp->av_forw)
- tcstart();
- else
- TCADDR->tccm.lobyte = SAT|GO;
- iodone(bp);
- return;
-
- case SFORW:
- if (*tcdtp > bp->b_blkno)
- goto setback;
- if (*tcdtp < bp->b_blkno)
- goto setforw;
- *--tcdtp = bp->b_addr; /* core address */
- *--tcdtp = bp->b_wcount;
- tccmp->lobyte = ((bp->b_xmem & 03) << 4) | IENABLE|GO
- | (bp->b_flags&B_READ?RDATA:WDATA);
- tctab.d_active = SIO;
- return;
-
- case SREV:
- if (*tcdtp+3 > bp->b_blkno)
- goto setback;
- goto setforw;
- }
- }
-