/*
 *
 *   SunDR11W.c
 *
 *     Copyright 1989, Xerox Corporation
 *     Dave Rumph, January 19, 1989 8:56:14 am PST
 *         last modified, November 5, 1990 8:23:24 pm PST
 *
 *
 */

#ifndef ←TYPES←
#include <sys/types.h>
#endif
#ifndef ←IOCTL←
#include <sys/ioctl.h>
#endif
#include <fcntl.h>
#include <xr/UIO.h>
#include <xr/ThreadsSlaveIOP.h>
#include "drreg.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

typedef int BOOL;

static int fd = -1;

static unsigned int drTimeout = XR←WAIT←FOREVER;

XR←Slave slave;

void DRStartUp ()
{
    slave = XR←SlaveStart();
};

BOOL DRInitializeProc ()
    {
        if ((fd = open("/dev/dr100", O←WRONLY, 0)) >= 0) return TRUE;
	return FALSE;
    };

void DRFinalizeProc ()
    {
        if (fd >= 0) {
            close(fd);
            fd = 0;
        };
    };

void DRResetProc ()
    {
        if (fd >= 0) {
            u←short control = DR←INIT;
            ioctl(fd, DR←IOCWSTAT, &control);
        };
    };


#define GetStatus(pstatus) ioctl(fd, DR←IOCRSTAT, pstatus)

void DRGetStatusProc (pstatus)
u←short *pstatus;
{
   if (fd >= 0) {
	ioctl(fd, DR←IOCRSTAT, pstatus);
	};
    };

void DRSetupProc ()
{
    if (fd >= 0) {
	u←short control = DR←FCN2;
	ioctl(fd, DR←IOCPULSE, &control);
    };
};

BOOL DRReadyProc ()
{
    u←short status;
    GetStatus(&status);
    return (status & DR←RDY);
};


static u←short dr11wControl = 0;

void DRSetControlProc (control)
    u←short control;
    {
        if (fd >= 0) {
            dr11wControl |= control;
            ioctl(fd, DR←IOCWSTAT, &dr11wControl);
        };
    };

void DRClearControlProc (control)
    u←short control;
    {
        if (fd >= 0) {
            dr11wControl &= ~control;
            ioctl(fd, DR←IOCWSTAT, &dr11wControl);
        };
    };

static u←short onWrite = DR←ISWRITE;

void DRSetOnWriteProc (control)
    u←short control;
    {
	if (fd >= 0) {
	    onWrite |= control;
	    ioctl(fd, DR←IOCISWRITE, &onWrite);
	};
    };

void DRClearOnWriteProc (control)
    u←short control;
    {
	if (fd >= 0) {
	    onWrite &= ~control;
	    ioctl(fd, DR←IOCISWRITE, &onWrite);
	};
    };

BOOL DRSendOneWordProc (data)
    u←short data;
    {
        if (fd >= 0) {
            u←short temp = data;
            if (write(fd, &temp, 2) == 1) return TRUE;
            else return FALSE;
         };
     };
 
typedef struct {
    long byteAddress;
    long byteCount;
    } DR←BufProcArgs;

BOOL DRSendBufferProc (pArgs)
    DR←BufProcArgs *pArgs;
    {
        if (fd >= 0) {
            if (write(fd, pArgs->byteAddress, pArgs->byteCount)
                 == pArgs->byteCount) return TRUE; 
            else return FALSE;
         };
     };

void DRAbortProc ()
    {
    /* do nothing for now */
    };

/**************** Procs exported to Threads PCedar  *******************/

BOOL DRInitialize ()
    {
        return (XR←SlaveCall(slave, DRInitializeProc, NIL, drTimeout));
    };

void DRFinalize ()
    {
        XR←SlaveCall(slave, DRFinalizeProc, NIL, drTimeout);
    };

void DRReset ()
    {
        XR←SlaveCall(slave, DRResetProc, NIL, drTimeout);
    };


void DRGetStatus (pstatus)
u←short *pstatus;
{
    XR←SlaveCall(slave, DRGetStatusProc, pstatus, drTimeout);
};

void DRSetup ()
{
    XR←SlaveCall(slave, DRSetupProc, NIL, drTimeout);
};

BOOL DRReady ()
{
    return (XR←SlaveCall(slave, DRReadyProc, NIL, drTimeout));
};
 
void DRSetControl (control)
u←short control;
{
    XR←SlaveCall(slave, DRSetControlProc, control, drTimeout);
};

void DRClearControl (control)
u←short control;
{
    XR←SlaveCall(slave, DRClearControlProc, control, drTimeout);
};

void DRSetOnWrite (control)
u←short control;
{
    XR←SlaveCall(slave, DRSetOnWriteProc, control, drTimeout);
};

void DRClearOnWrite (control)
u←short control;
{
    XR←SlaveCall(slave, DRClearOnWriteProc, control, drTimeout);
};

BOOL DRSendOneWord (data)
u←short data;
{
    return (XR←SlaveCall(slave, DRSendOneWordProc, data, drTimeout));

};
 
BOOL DRSendBuffer (byteAddress, byteCount)
long byteAddress, byteCount;
{
    DR←BufProcArgs args;
    args.byteAddress = byteAddress;
    args.byteCount = byteCount;
    return (XR←SlaveCall(slave, DRSendBufferProc, &args, drTimeout));

};

void DRAbort ()
    {
    /* do nothing for now */
    };