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

#ifndef ←TYPES←
#include <sys/types.h>
#endif
#include <fcntl.h>
#include <xr/UIO.h>
#include <xr/ThreadsSlaveIOP.h>
#include "lpcmd.h"
#include "lpioctl.h"
#include "Versatec.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define CDS←OnLine 0x1000
#define CDS←Ready 0x4000

typedef int BOOL;

static int fd = -1;

static unsigned int svTimeout = XR←WAIT←FOREVER;

XR←Slave slave;

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

/******************  Procs to be called on Slave IOP  *******************/

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

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

void SVResetProc ()
    {
        if (fd >= 0) {
            int command = LPC←MCLR;
            ioctl(fd, LPCOMMAND, &command);
        };
    };


#define GetStatus(pregs) ioctl(fd, LPGETREGS, pregs)

BOOL SVOnLineProc ()
{
    struct lpregs regs;
    GetStatus(&regs);
    return (regs.cdsreg & CDS←OnLine);
};

BOOL SVReadyProc ()
{
    struct lpregs regs;
    GetStatus(&regs);
    return (regs.cdsreg & CDS←Ready);
};

void SVSetModeProc (mode)
    int mode;
    {
        if (fd >= 0) {
            int command;
            switch (mode) {
            case PRINT:
                command = LPC←DVPT | LPC←DSPP; /* disable plot, disable SPP */
                break;
            case PLOT:
                command = LPC←VPLT | LPC←DSPP; /* enable plot, disable SPP */
                break;
            case SPPPrint:
                command = LPC←DVPT | LPC←VSPP; /* disable plot, enable SPP */
                break;
            case SPPPlot:
                command = LPC←VPLT | LPC←VSPP; /* enable plot, enable SPP */
                break;
            default:
                command = 0; /* no command! */
                };
            ioctl(fd, LPCOMMAND, &command);

        };
    };

BOOL SVSendRCommandProc (cmd)
    int cmd;
    {
        int command;
        if (fd < 0) return FALSE;
        switch (cmd) {
        case CLEAR:
            command = LPC←VCLR;
            break;
        case RESET:
            command = LPC←MCLR;
            break;
        case RLTER:
            command = LPC←VLTR;
            break;
        case RFFED:
            command = LPC←VTFF;
            break;
        case REOTR:
            command = LPC←VEOT;
            break;
        default:
            command = 0; /* nothing to do! */
            };
        ioctl(fd, LPCOMMAND, &command);
	return TRUE;
    };
 
BOOL SVSendOneByteProc (data)
    char data;
    {
        if (fd >= 0) {
            char temp = data;
            if (write(fd, &temp, 1) == 1) return TRUE;
            else return FALSE;
         };
     };
 
typedef struct {
    long byteAddress;
    long byteCount;
    long dmaPerTransferCount;
    } SV←BufProcArgs;

BOOL SVSendBufferProc (pArgs)
    SV←BufProcArgs *pArgs;
    {
        if (fd >= 0) {
            ioctl(fd, LPSETDMACOUNT, &(pArgs->dmaPerTransferCount));
            if (write(fd, pArgs->byteAddress, pArgs->byteCount)
                 == pArgs->byteCount) return TRUE; 
            else return FALSE;
         };
     };

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

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

BOOL SVInitialize ()
    {
        return (XR←SlaveCall(slave, SVInitializeProc, NIL, svTimeout));
    };

void SVFinalize ()
    {
        XR←SlaveCall(slave, SVFinalizeProc, NIL, svTimeout);
    };

void SVReset ()
    {
        XR←SlaveCall(slave, SVResetProc, NIL, svTimeout);
    };


BOOL SVOnLine ()
{
    return (XR←SlaveCall(slave, SVOnLineProc, NIL, svTimeout));
};

BOOL SVReady ()
{
    return (XR←SlaveCall(slave, SVReadyProc, NIL, svTimeout));
};

void SVSetMode (mode)
int mode;
{
    XR←SlaveCall(slave, SVSetModeProc, mode, svTimeout);
};

BOOL SVSendRCommand (cmd)
int cmd;
{
    return (XR←SlaveCall(slave, SVSendRCommandProc, cmd, svTimeout));
};
 
BOOL SVSendOneByte (data)
char data;
{
    return (XR←SlaveCall(slave, SVSendOneByteProc, data, svTimeout));

};
 
BOOL SVSendBuffer (byteAddress, byteCount, dmaPerTransferCount)
long byteAddress, byteCount, dmaPerTransferCount;
{
    SV←BufProcArgs args;
    args.byteAddress = byteAddress;
    args.byteCount = byteCount;
    args.dmaPerTransferCount = dmaPerTransferCount;
    return (XR←SlaveCall(slave, SVSendBufferProc, &args, svTimeout));

};

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