BSD 3 development
[unix-history] / usr / src / sys / sys / vp.c
/* vp.c 2.1 1/5/80 */
#ifdef ERNIE
#include "../h/param.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/buf.h"
#include "../h/systm.h"
#include "../h/map.h"
#include "../h/pte.h"
#include "../h/uba.h"
/*
* Versatec matrix printer/plotter
* dma interface driver
*/
int vpbdp = 1;
unsigned minvpph();
#define VPPRI (PZERO-1)
struct vpregs {
short plbcr;
short fill;
short prbcr;
unsigned short pbaddr;
short plcsr;
short plbuf;
short prcsr;
unsigned short prbuf;
};
#define VPADDR ((struct vpregs *)(UBA0_DEV + 0177500))
#define ERROR 0100000
#define DTCINTR 040000
#define DMAACT 020000
#define READY 0200
#define IENABLE 0100
#define TERMCOM 040
#define FFCOM 020
#define EOTCOM 010
#define CLRCOM 04
#define RESET 02
#define SPP 01
struct {
int vp_state;
int vp_count;
int vp_bufp;
} vp11;
struct buf rvpbuf;
#define VISOPEN 01
#define CMNDS 076
#define MODE 0700
#define PRINT 0100
#define PLOT 0200
#define PPLOT 0400
#define VBUSY 01000
vpopen()
{
if (vp11.vp_state & VISOPEN) {
u.u_error = ENXIO;
return;
}
vp11.vp_state = VISOPEN | PRINT | CLRCOM | FFCOM | RESET;
vp11.vp_count = 0;
VPADDR->prcsr = IENABLE | DTCINTR;
vptimo();
while (vp11.vp_state & CMNDS) {
VOID spl4();
if (vperror(READY)) {
vpclose();
u.u_error = EIO;
return;
}
vpstart();
VOID spl0();
}
}
vpstrategy(bp)
register struct buf *bp;
{
register int e;
register int ubainfo;
VOID spl4();
while (vp11.vp_state & VBUSY)
sleep((caddr_t)&vp11, VPPRI);
vp11.vp_state |= VBUSY;
VOID spl0();
ubainfo = ubasetup(bp, vpbdp);
vp11.vp_bufp = ubainfo & 0x3ffff;
VOID spl4();
if (e = vperror(READY))
goto brkout;
vp11.vp_count = bp->b_bcount;
vpstart();
while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT)
sleep((caddr_t)&vp11, VPPRI);
vp11.vp_count = 0;
vp11.vp_bufp = 0;
if ((vp11.vp_state&MODE) == PPLOT)
vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT;
VOID spl0();
brkout:
ubafree(ubainfo);
vp11.vp_state &= ~VBUSY;
iodone(bp);
if (e)
u.u_error = EIO;
wakeup((caddr_t)&vp11);
}
int vpblock = 16384;
unsigned
minvpph(bp)
struct buf *bp;
{
if (bp->b_bcount > vpblock)
bp->b_bcount = vpblock;
}
/*ARGSUSED*/
vpwrite(dev)
{
physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph);
}
vperror(bit)
{
register int state, e;
state = vp11.vp_state & PLOT;
while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0)
sleep((caddr_t)&vp11, VPPRI);
return (e & ERROR);
}
vpstart()
{
register short bit;
if (vp11.vp_count) {
VPADDR->pbaddr = vp11.vp_bufp;
if (vp11.vp_state & (PRINT|PPLOT))
VPADDR->prbcr = vp11.vp_count;
else
VPADDR->plbcr = vp11.vp_count;
return;
}
for (bit = 1; bit != 0; bit <<= 1)
if (vp11.vp_state&bit&CMNDS) {
VPADDR->plcsr |= bit;
vp11.vp_state &= ~bit;
return;
}
}
/*ARGSUSED*/
vpioctl(dev, cmd, addr, flag)
register caddr_t addr;
{
register int m;
switch (cmd) {
case ('v'<<8)+0:
VOID suword(addr, vp11.vp_state);
return;
case ('v'<<8)+1:
m = fuword(addr);
if (m == -1) {
u.u_error = EFAULT;
return;
}
vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS));
break;
default:
u.u_error = ENOTTY;
return;
}
VOID spl4();
VOID vperror(READY);
if (vp11.vp_state&PPLOT)
VPADDR->plcsr |= SPP;
else
VPADDR->plcsr &= ~SPP;
vp11.vp_count = 0;
while (CMNDS & vp11.vp_state) {
VOID vperror(READY);
vpstart();
}
VOID spl0();
}
vptimo()
{
if (vp11.vp_state&VISOPEN)
timeout(vptimo, (caddr_t)0, HZ/10);
vpintr(0);
}
/*ARGSUSED*/
vpintr(dev)
{
wakeup((caddr_t)&vp11);
}
vpclose()
{
vp11.vp_state = 0;
vp11.vp_count = 0;
vp11.vp_bufp = 0;
VPADDR->plcsr = 0;
}
#endif