#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include <string.h>
#include "pcicall.h"

BYTE    *PCIname = "RAYONPCIOP";

#define PACKPORT(card,port)     (WORD) ( ( card << 8 ) + port )

/* ************************************ */
/*        INT 14H PCI FUNATION          */
/* ************************************ */

INT     PciPortGetc(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Read a character from PCI port
*/
WORD    card;
WORD    port;
{
        union REGS regs;
        BYTE    c;

        regs.h.ah = F_GETC;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        c = regs.h.al;
        return (c);
}


INT     PciPortOpen(card, port, cflag, iflag) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Open a PCI port, and initialize some of its parameters.
*/
WORD    card;
WORD    port;
WORD    cflag;
WORD    iflag;
{
        union REGS regs;

        regs.h.ah = F_OPEN;
        regs.x.bx = cflag;
        regs.x.cx = iflag;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}


INT     PciPortPutc(card, port, c) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Send one character to PCI port.
*/
WORD    card;
WORD    port;
BYTE    c;

{
        union REGS regs;

        regs.h.ah = F_PUTC;
        regs.h.al = c;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

INT     PciPortRead(card, port, buffer, count) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Read characters from a PCI port to user buffer.
*       Returns Actually read byte count.
*/
WORD    card;
WORD    port;
BYTE    far *buffer;
INT     count;
{
        union REGS regs;
        struct SREGS sregs;


        segread(&sregs);
        regs.h.ah = F_READ;
        regs.x.dx = PACKPORT(card, port);
        regs.x.cx = count;
        sregs.es = FP_SEG(buffer);
        regs.x.bx = FP_OFF(buffer);
        int86x(PCINT, &regs, &regs, &sregs);
        return ( regs.x.ax );
}

INT     PciPortWrite(card, port, buffer, count) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Write characters in buffer to a specified serial port.
*       Returns Actually write byte count.
*/
WORD    card;
WORD    port;
BYTE    far *buffer;
INT     count;
{
        union REGS regs;
        struct SREGS sregs;

        segread(&sregs);
        regs.h.ah = F_WRITE;
        regs.x.dx = PACKPORT(card, port);
        regs.x.cx = count;
        sregs.es = FP_SEG(buffer);
        regs.x.bx = FP_OFF(buffer);
        int86x(PCINT, &regs, &regs, &sregs);
        return ( regs.x.ax );
}




INT     PciPortDoqSpace(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Get available output queue space of PCI port.
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_DOQSPC;

        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return (regs.x.ax);
}

INT     PciPortDiqCount(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Get how many bytes in input queue of PCI port.
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_DIQCNT;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return (regs.x.ax);
}

WORD    PciPortStatus(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Get port status
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_STATUS;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

WORD    PciPortGetStatus(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Get LSR,MSR status
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_GETSTATUS;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

INT     PciPortMaxCard() /*
~~~~~~~~~~~~~~~~~~~~~
*
*       Get how many cards on the main board.
*/
{
        union REGS regs;

        regs.h.ah = F_MAXCARD;
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

INT     PciPortMaxPort(card) /*
~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Get the maximum ports of a PCI port.
*/
WORD    card;
{
        union REGS regs;

        regs.h.ah = F_MAXPORT;
        regs.h.al = card & 0xFF;
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

INT     PciPortResetDoq(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Reset the output queue of a specified port.
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_RESETDOQ;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

INT     PciPortResetDiq(card, port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Reset the input queue of a specified port.
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_RESETDIQ;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}

VOID    PciPortReset() /*
~~~~~~~~~~~~~~~~~~~~~
*
*       Restart PCI.
*/
{
        union REGS regs;

        regs.h.ah = F_RESETPCI;
        int86(PCINT,&regs,&regs);
}

INT     PciPortSetDTR(card, port, flag) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Turn the DTR of a specified port ON or OFF.
*/
WORD    card;
WORD    port;
INT     flag;   /* 0 : turn off,  1 : turn on */
{
        union   REGS regs;

        regs.h.ah = F_DTR;
        regs.x.dx = PACKPORT(card, port);
        regs.h.al = (BYTE) flag;
        int86(PCINT, &regs, &regs);
        return(regs.x.ax);
}


INT     PciPortSetRTS(card, port, flag) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Turn the RTS of a specified port ON or OFF.
*/
WORD    card;
WORD    port;
INT     flag;   /* 0 : turn off,  1 : turn on */
{
        union   REGS regs;

        regs.h.ah = F_RTS;
        regs.x.dx = PACKPORT(card, port);
        regs.h.al = (BYTE) flag;
        int86(PCINT, &regs, &regs);
        return(regs.x.ax);
}



INT     PciPortClose(card,port) /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Close a specified serial port.
*/
WORD    card;
WORD    port;
{
        union REGS regs;

        regs.h.ah = F_CLOSE;
        regs.x.dx = PACKPORT(card, port);
        int86(PCINT,&regs,&regs);
        return(regs.x.ax);
}


INT     PciPortInstall() /*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
*       Check to see if driver was installed.
*/
{
        union REGS regs;
        struct SREGS sregs;
        BYTE far *p;
        BYTE far *q;
        register INT    i;

        segread(&sregs);
        q = (BYTE far *) PCIname;
        regs.h.ah = 0x35;
        regs.h.al = F_INSTALL;
        int86x(DOSINT, &regs, &regs, &sregs);
        p = MK_FP(sregs.es, regs.x.bx);
        p -= 10;
        for (i = 0; i < 10; i++)
        {
                if ( *p++ != *q++ )
                        return(FALSE);
        }
        return(TRUE);
}

