LSX/sys/sykfd.c
#
/*
* Copyright 1976 Bell Telephone Laboratories Inc
*/
/*
* Sykes FD disk driver
*/
#include "param.h"
#include "buf.h"
#include "user.h"
#define RESET 0200
#define UNIT1 0201
#define UNIT2 0202
#define TERM 0203
#define IENABLE 0100
#define DONE 0200
#define FDWRITE 040
#define FDREAD 0
#define BUSY 04
#define FAULT 0100
#define CRCERR 010
#define FDVECT 0174
#define FDPS 0176
#define NFD 2
#define NFDBLK 500
#define FDADR 0176000
struct {
int integ;
};
struct {
int flfg;
int flcm;
int flst;
int flda;
};
struct devtab fdtab;
int sect;
int hbuf[40];
int *hp hbuf;
fdstrategy(abp)
struct buf *abp;
{
register struct buf *bp;
bp = abp;
if (bp->b_blkno >= NFDBLK) {
bp->b_flags =| B_DONE | B_ERROR;
return;
}
bp->b_link = 0;
spl7();
if (fdtab.d_actf==0)
fdtab.d_actf = bp;
else
fdtab.d_actl->b_link = bp;
fdtab.d_actl = bp;
if (fdtab.d_active==0)
fdstart();
spl0();
}
fdstart()
{
register struct buf *bp;
register int i;
register char *cp;
if ((bp = fdtab.d_actf) == 0)
return;
fdtab.d_active++;
FDADR->flcm = RESET;
FDADR->flcm = bp->b_dev?UNIT2:UNIT1;
FDADR->flcm = (i = bp->b_blkno*4)/26;
FDADR->flcm = ((i%26) + 1) | ((bp->b_flags&B_READ)?FDREAD:FDWRITE);
if((bp->b_flags&B_READ) == 0) {
cp = bp->b_addr+sect*128;
for(i = 0; i < 128; i++) {
while((FDADR->flfg&DONE) == 0);
FDADR->flda = *cp++;
}
}
}
fdintr()
{
register struct buf *bp;
register int i;
register char *cp;
if (fdtab.d_active == 0)
return;
bp = fdtab.d_actf;
fdtab.d_active = 0;
FDADR->flfg = 0;
if(bp->b_flags&B_READ) {
cp = bp->b_addr+sect*128;
for(i = 0; i < 128; i++) {
while((FDADR->flfg&DONE) == 0);
*cp++ = FDADR->flda;
}
}
FDADR->flcm = TERM;
while(FDADR->flst&BUSY);
if(FDADR->flst&(FAULT|CRCERR)) {
*hp++ = FDADR->flst;
if(hp >= &hbuf[40])
hp = hbuf;
if (++fdtab.d_errcnt <= 10) {
fdstart();
return;
}
bp->b_flags =| B_ERROR;
}
fdtab.d_errcnt = 0;
if((bp->b_wcount =+ 64) == 0) {
fdtab.d_actf = bp->b_link;
bp->b_flags =| B_DONE;
#ifdef BGOPTION
wakeup(bp);
#endif
sect = 0;
} else {
if(++sect == 4) {
sect = 0;
bp->b_blkno++;
bp->b_addr =+ 512;
}
}
fdstart();
}