/*
 * Digital I/O    (DIO)
 *
 * This driver supports the digital I/O module interface
 * (DIOM).
 *
 * This version is output-only.
 */

#include "../h/local.h"

#ifdef  SCCS_ID
static char SCCS_ID [] = "@(#)dio.c    	1.1	 16:18:47 - 83/02/23 ";
#endif  SCCS_ID

#include "../h/param.h"
#include "../h/dir.h"
#include "../h/user.h"

#define MAXLINES        32
#define LINESPERBOARD   16

extern  char    dioaddr[];
extern  int     ndio;

/* state bits */
#define DIOENABLE       0x01            /* Line is open and enabled */

struct diotab {
	char    dio_state;
};

static struct diotab diotab[MAXLINES];
static short         dioval[MAXLINES/LINESPERBOARD];

dioopen(dev, flag)
  dev_t dev;
  int   flag;
{
    int         minr;

    minr = minor(dev);
    if (0 <= minr && minr < ndio*LINESPERBOARD)
	if (flag)
	    if (!(diotab[minr].dio_state & DIOENABLE)) {
		diotab[minr].dio_state = DIOENABLE;
	    } else
		u.u_error = EBUSY;
	else
	    u.u_error = EACCES;
    else
	u.u_error = ENXIO;
}

dioclose(dev)
  dev_t  dev;
{
    diotab[minor(dev)].dio_state = 0;
}

diowrite(dev)
{
	register minr;
	register c;

	minr = minor(dev);
	while ((c=cpass()) >= 0)
		diocanon(minr, c);
}

diocanon (line, c) {
    register    board;
    register    bit;

    board = line/LINESPERBOARD;
    bit   = line%LINESPERBOARD;

    if (((dioval[board] >> (15-bit)) & 1) != (c & 1)) {
	if (c & 1)
	    dioval[board] |=  (1 << (15-bit));
	else
	    dioval[board] &= ~(1 << (15-bit));

	wdh (dioaddr[board], dioval[board]);
    }
}

dioioctl(dev, cmd, addr, flag)
  dev_t   dev;
  caddr_t addr;
{
}

/*
 * Dummy routine for future use.
 */

dioint(dev, status) {
}
