/* Copyright 1987 by the Massachusetts Institute of Technology */
/* See permission and disclaimer notice in file notice.h */
#include <notice.h>

/* Device driver for a DL-11 interface.  Written for the uVAX.
 * Actually, this driver was written for a Plessy Dl-11 clone which
 * has many DL-11F capabilities.  Any strangeness about the driver wrt
 * a real DL-11 is probably due to that.
 */

/*
 *------------------------------------------------------------------
 *
 * $Source: /mit/cgw/src/gw/dev.vax/RCS/dl.c,v $
 * $Revision: 1.1 $
 * $Date: 88/06/05 22:43:03 $
 * $State: Exp $
 * $Author: jon $
 * $Locker: jon $
 *
 * $Log:	dl.c,v $
 * Revision 1.1  88/06/05  22:43:03  jon
 * Initial revision
 * 
 *------------------------------------------------------------------
 */

#ifndef lint
static char *rcsid_dl_c = "$Header: dl.c,v 1.1 88/06/05 22:43:03 jon Locked $";
#endif	lint

#include	<types.h>
#include	<sys.h>
#include	<gw/src/status.h>
#include	"dl.h"

/* device init (it's a pretty simple device) */
dlup(devp)
dct *devp;
{
    devp->d_flg |= D_INI;
}

/* input transfer initialization routine - */
dlin(devp)
dct *devp;
{
    struct dl_reg *dreg = (struct dl_reg *)devp->d_csr;

    /* d_rfnt and d_rend are used to keep track of the bytes as they
     * come in one at a time. */
    devp->d_rfnt = devp->d_addr;
    devp->d_rend = devp->d_addr + devp->d_breq;
    dreg->rcsr |= DL_RXIE;
}

/* output transfer initialization routine */
dlot(devp)
dct *devp;
{
    struct dl_reg *dreg = (struct dl_reg *)devp->d_csr;

    /* d_rfnt and d_rend are used to keep track of the bytes as they
     * are sent one at a time. */
    devp->d_rfnt = devp->d_addr;
    devp->d_rend = devp->d_addr + devp->d_breq;

    /* This should cause an immediate interrupt */
    dreg->xcsr |= DL_TXIE;
}

/* input interrupt routine */
dlii(devp)
dct *devp;
{
    struct dl_reg *dreg = (struct dl_reg *)devp->d_csr;

    while (dreg->rcsr & DL_RXDONE)
      if (devp->d_rc)
	(*((int (*)())devp->d_rc)) (devp, dreg->rbuf & ~DL_ERROR);
}

/* output interrupt routine */
dloi(devp)
dct *devp;
{
    struct dl_reg *dreg = (struct dl_reg *)devp->d_csr;

    if (devp->d_qhd != 0) {
	dreg->xbuf = *devp->d_rfnt++;
	if (devp->d_rfnt == devp->d_rend) {
	    iorb *iob = devp->d_qhd;
	    dreg->xcsr &= ~DL_TXIE;
	    iob->i_stat |= I_DONE;
	    iob->i_bxfr = devp->d_breq;
	    iocmr(devp);
	}
    }
}
