LSX/sys/decfd.c
#
/*
* Copyright 1975 Bell Telephone Laboratories Inc
*/
/*
* FD disk driver
*/
#include "param.h"
#include "buf.h"
#include "user.h"
#define ERR 0100000
#define INIT 040000
#define TR 0200
#define IENABLE 0100
#define DONE 040
#define UNIT 020
#define FILLBUF 0
#define EMPBUF 02
#define FDWRITE 04
#define FDREAD 06
#define GO 01
#define FDVECT 0264
#define FDPS 0266
#define NFD 2
#define NFDBLK 500
#define FDADR 0177170
/*
* Comment out next line if logical to physical track mapping
* is not to be performed. Also, change boot.s and header.s
*/
#define IBMS 1
struct {
int integ;
};
struct {
int rxcs;
int rxdb;
};
struct devtab fdtab;
int sect;
/* debugging circular buffer
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 *FD;
register char *cp;
if ((bp = fdtab.d_actf) == 0)
return;
fdtab.d_active++;
FD = FDADR;
if((bp->b_flags&B_READ) == 0) {
#ifdef EIS
cp = bp->b_addr+sect*128;
#endif
#ifndef EIS
cp = bp->b_addr + (sect<<1<<1<<1<<1<<1<<1<<1);
#endif
FD->rxcs = FILLBUF | GO;
while((FD->rxcs&DONE) == 0) {
if(FD->rxcs&TR)
FD->rxdb = *cp++;
}
if(FD->rxcs & ERR) {
panic();
}
}
while((FD->rxcs&DONE) == 0);
#ifdef EIS
FD->rxcs = (bp->b_dev<<4) | IENABLE | ((bp->b_flags&B_READ)?FDREAD:FDWRITE) | GO;
#endif
#ifndef EIS
FD->rxcs = (bp->b_dev<<1<<1<<1<<1) | IENABLE | ((bp->b_flags&B_READ)?FDREAD:FDWRITE) | GO;
#endif
while((FD->rxcs&TR) == 0);
#ifdef EIS
FD->rxdb = (((bp->b_blkno*4 + sect)*3)%26)+1;
while((FD->rxcs&TR) == 0);
#ifdef IBMS
cp = (bp->b_blkno*4 + sect)/26 + 1;
if (cp == 77)
cp = 0;
FD->rxdb = cp;
#endif
#ifndef IBMS
FD->rxdb = (bp->b_blkno*4 + sect)/26;
#endif
#endif
#ifndef EIS
decmch((bp->b_blkno<<1<<1)+sect);
#endif
}
fdintr()
{
register struct buf *bp;
register int *FD;
register char *cp;
if (fdtab.d_active == 0)
return;
bp = fdtab.d_actf;
fdtab.d_active = 0;
FD = FDADR;
if(FD->rxcs&ERR) {
/*
*hp++ = FD->rxdb;
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_flags&B_READ) {
#ifdef EIS
cp = bp->b_addr+sect*128;
#endif
#ifndef EIS
cp = bp->b_addr+(sect<<1<<1<<1<<1<<1<<1<<1);
#endif
FD->rxcs = EMPBUF | GO;
while((FD->rxcs&DONE) == 0) {
if(FD->rxcs&TR)
*cp++ = FD->rxdb;
}
if(FD->rxcs & ERR) {
panic();
}
}
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();
}