Add original unix v6
This commit is contained in:
+171
@@ -0,0 +1,171 @@
|
||||
#
|
||||
/*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user