The PortIO95 Parallel Port Interface

Sample Source: writedat.c

/* ****************************************************************************
 * writedat.c - This file provides example code illustrating the use of the
 *              PortIO95 VxD. Its function is to cycle through the pins on the
 *              data register of the specified LPT port setting each one on in 
 *              turn. If you hook up a series of LEDs and 330 ohm resistors as 
 *              shown below, you should see the lights cycle on and off in sequence.
 *
 *        Pins on the Parallel Port D connector
 *            2  3  4  5  6  7  8  9     18
 *            |  |  |  |  |  |  |  |     |
 *            |  |  |  |  |  |  |  |     |      Note: V is a LED Diode
 *            V  V  V  V  V  V  V  V     |            Z is a 330 ohm resistor
 *            |  |  |  |  |  |  |  |     |
 *            |  |  |  |  |  |  |  |     |      Note: Pin 2 is D0, Pin 9 is D7
 *            Z  Z  Z  Z  Z  Z  Z  Z     |            Pin 18 is Gnd
 *            |  |  |  |  |  |  |  |     |
 *            ----------------------------
 *
 *              As written, this program compiles cleanly under Visual C++ 4.0 
 *              using the command line compiler. It is designed to work only
 *              with the PortIO95 parallel port handler VxD
 *              
 * Note: This file is best viewed with tab stops of 4
 *
 * DISCLAIMER !!!
 * There is no warranty - you use PortIO95 entirely at your own risk.  Net 2000 Ltd. does
 * not warrant PortIO95's suitability for any purpose, does not guarantee PortIO95's
 * uninterrupted functionality, or even its functionality. Net 2000 Ltd. is not liable
 * for any damage or loss that may occur to you, your computer or the things that your
 * computer is controlling.
 *
 * NOTE: This program uses LPT1 by default. See the variable cPortToUse below to change this.
 *
 * See the PortIO95 documentation and FAQ at http://ds.dial.pipex.com/town/close/ec63 for
 * more information.
 *
 * Copyright (c) 1997 Net 2000 Ltd.
 */
 
#include 
#include 
#include 
#include 
#include "portio95.h"

#define PAUSETIME 250    /* led on time in milli seconds */

/* function prototypes */
void Handle_Error(char *);

/* ##### IMPORTANT ##### Change this to the port you wish to use */
char cPortToUse='1';     /* set it for '1'=LPT1, '2'=LPT2, '3'=LPT3 */
char cInData;      ;     /* use this byte to send data to PortIO95 */

/* global variables */
HANDLE        hDevice;

void main(int ac, char* av[])
    {
    BOOL    retval;
    int     i;
    DWORD    err;

    /* Load the name of the vxd in here where we can pass it as a pointer
     * Note that the format is really "\\.\VXDNAME.VXD" but we have to
     * escape the back slashes with more back slashes because of the
     * special significance the backslash has in C */
    const PCHAR VxDName = "\\\\.\\PORTIO95.VXD";
    printf("\n");
    printf("Preparing to Dynamically Load VxD ->%s\n",VxDName);

    /* the VxD opens just like a regular file. Windows will look for it as follows:
     *   * if it has an .VXD extension
     *     - current directory
     *     - windows directory
     *     - on the path (the autoexec.bat one that win95 sees when it starts)
     *   * if there is no .VXD extension
     *     - in the registry under the KnownVxD's Key
     * see [HAZZAH 227]. The FILE_FLAG_DELETE_ON_CLOSE will cause the VxD to
     * be dynamically removed when the program ends. */
    hDevice = CreateFile(VxDName, 0,0,0,CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0);

    /* By now the PortIO95 VxD should be loaded - lets check */
    if (hDevice == INVALID_HANDLE_VALUE)
        {
        /* Get the Last Error Value see also [PortIO95.doc, Appendix A] */
        err = GetLastError();
           printf("Could Not Load VxD, error=%08lx\n", err );

        /* There is one error we have to handle carefully. It implies that
         * the PortIO95 VxD was found ok but didn't handle the dyamic
         * loading properly. This error shouldn't happen. But if it
         * does we cope with it here. We dynamically unload the vxd
         * before we exit. NOTE there is no .VXD extension on this call
         * otherwise you really do delete the VXD file rather than just
         * forcing an unload. */
        if (err == ERROR_NOT_SUPPORTED) DeleteFile("\\\\.\\PORTIO95");
         exit(1);
        }

    /* now lets set the PortIO95 Vxd to use an LPT for its Input and output */
    retval=DeviceIoControl(hDevice, PORTIO_SETPORT, &cPortToUse, sizeof(cPortToUse), NULL, 0, NULL, NULL);
    if (!retval) Handle_Error("PORTIO_SETPORT");
    printf("PortIO95 set to use LPT%c\n",cPortToUse);

    /* first we will write a zero byte to pins 2 to 9 to turn
     * them all off. The byte we write here overwites the existing
     * output byte. This has the effect of setting pins 2-9 low */
    cInData=0;    /* output a zero to the register */
    retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
    if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");

    /* this loop will execute 3 times turning each led on and off in turn
     * with a short pause bettween each activation. Not too elegant as code,
     * but serves the purpose none the less. You could add the checks to 
     * the retval here (the same as shown above on the PORTIO_SEND_BYTE_TO_PINS2_TO_9 call) if you wish.
     * The PORTIO_PIN*HIGH and PORTIO_PIN*LOW calls affect only the specified pins
     * the other pins on the LPT port are unaffected */
    for (i=0; i<3; i++)
        {

        retval=DeviceIoControl(hDevice, PORTIO_PIN2HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN2LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN3HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN3LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN4HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN4LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN5HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN5LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN6HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN6LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN7HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN7LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN8HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN8LOW, NULL, 0, NULL, 0, NULL, NULL);

        retval=DeviceIoControl(hDevice, PORTIO_PIN9HIGH, NULL, 0, NULL, 0, NULL, NULL);
        Sleep(PAUSETIME);        /* wait for a short time */
        retval=DeviceIoControl(hDevice, PORTIO_PIN9LOW, NULL, 0, NULL, 0, NULL, NULL);
        
        }

    cInData=0xAA;           /* turn every second pin off */
    retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
    if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");
    Sleep(4*PAUSETIME);        /* wait for a short time */

    cInData=0x55;           /* turn every other second pin off */
    retval=DeviceIoControl(hDevice, PORTIO_SEND_BYTE_TO_PINS2_TO_9, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
    if (!retval) Handle_Error("PORTIO_SEND_BYTE_TO_PINS2_9");
    Sleep(4*PAUSETIME);        /* wait for a short time */

    /* make sure all of the Data Register Bytes are turned off */
    cInData=0;    /* output a zero to the register */
    retval=DeviceIoControl(hDevice, PORTIO_WRITEDREG, &cInData, sizeof(cInData), NULL, 0, NULL, NULL);
    if (!retval) Handle_Error("PORTIO_WRITEDREG");

    /* unset our port, this is desireable as it resets things */
    retval=DeviceIoControl(hDevice, PORTIO_UNSETPORT, NULL, 0, NULL, 0, NULL, NULL);

    CloseHandle( hDevice );
    }
    
/* ********************************************************************
 * Handle_Error - a simple function to print out errors for us
 *               Saves having to put this code after every call
 *
 */
void Handle_Error(char * szErrStr)
        {
        printf("%s DeviceIoControl failed, error=%d\n", szErrStr, GetLastError() );
        exit (1);
        }
    

[Previous] [PortIO95 Home][PortIO95 Source Home] [Next]