/* DOS program that returns the level on one of the digital inputs. Syntax: DIN CHANNEL Optional LPT port number - defaults to LPT1 CHANNEL Digital input channel number (0 - 15) On exit: ERRORLEVEL = 0 if input is low ERRORLEVEL = 1 if input is high ERRORLEVEL = 2 if error */ #include #include #include #define LPT1 0x00400008 /* BIOS printer address entries */ #define LPT2 0x0040000a #define LPT3 0x0040000c #define LPT4 0x0040000e #define PLOAD 0x01 /* Parallel load bit */ #define CLK 0x02 /* Clock bit */ #define PE 0x20 /* Data bit */ /*----------------------------------------------------------------------*/ union digital_input { unsigned int a; unsigned char x[2]; }; /*------------------ Prototype Declarations ----------------------------*/ unsigned int get_inputs(unsigned int port); /*------------------ Program starts here -------------------------------*/ int main(int argc, char *argv[]) { unsigned int port, /* LPT port address */ channel; /* Input channel number */ unsigned int far *bios_printer_addr; union digital_input data; /* Input data from all 16 channels */ int lpt_number, /* LPT port number */ x; unsigned char temp; switch(argc) { case 1: printf("Read & display the digital level on the specified input.\n\n"); printf("DIN CHANNEL\n\n"); printf(" Optional LPT port number - defaults to LPT1.\n"); printf("CHANNEL Digital input channel number (0 - 15).\n\n"); printf("On exit, ERRORLEVEL = 0 if input is low.\n"); printf(" ERRORLEVEL = 1 if input is high.\n"); printf(" ERRORLEVEL = 2 if parameter error.\n"); exit(2); case 2: if (argv[1][0]=='/') { puts("Missing channel number"); exit(2); } port=*(bios_printer_addr=LPT1); if (port==NULL) { puts("LPT1 does not exist"); exit(2); } sscanf(argv[1],"%d",&channel); break; case 3: if (argv[1][0]=='/') lpt_number=atoi(argv[1]+1); switch(lpt_number) { case 1 : port=*(bios_printer_addr=LPT1); if (port==NULL) { puts("LPT1 does not exist"); exit(2); } sscanf(argv[2],"%d",&channel); break; case 2 : port=*(bios_printer_addr=LPT2); if (port==NULL) { puts("LPT2 does not exist"); exit(2); } sscanf(argv[2],"%d",&channel); break; case 3 : port=*(bios_printer_addr=LPT3); if (port==NULL) { puts("LPT3 does not exist"); exit(2); } sscanf(argv[2],"%d",&channel); break; case 4 : port=*(bios_printer_addr=LPT4); if (port==NULL) { puts("LPT4 does not exis"); exit(2); } sscanf(argv[2],"%d",&channel); break; default: puts("Invalid printer port"); exit(2); } } if ((channel>15) || (channel<0)) { puts("Invalid channel number"); exit(2); } outportb(port,PLOAD); /* "PL" high, "CLK" low */ delay(1); outportb(port,0); /* "PL & CLK" both low */ delay(1); outportb(port,CLK); /* "PL" low, "CLK" high This loads inputs into shift registers */ delay(1); outportb(port,PLOAD); /* "PL" high, "CLK" low */ delay(1); data.a=get_inputs(port); /* Read digital inputs */ temp=data.x[0]; /* Swap upper & lower bytes in the 16-bit data */ data.x[0]=data.x[1]; data.x[1]=temp; data.a=data.a>>channel; /* Shift channel bit into bit position 0 */ data.a=data.a&1; /* Mask off all other bits 1-15 */ printf("Digital input %d = %d\n",channel,data.a); return(data.a); /* Return channel data (0 or 1) */ } /*-------------------- Program functions here ---------------------------*/ /* Read in 16 bits from 74166 shift registers */ unsigned int get_inputs(unsigned int port) { unsigned int data=0,bits; int x; bits=inportb(port+1); /* Read data bits */ if (bits&PE) data=data|1; /* Set data bit if bit 7 is set */ for (x=0; x<15; x++) { data=data<<1; outportb(port,PLOAD|CLK); /* Shift next bit out of shift registers */ delay(1); outportb(port,PLOAD); delay(1); bits=inportb(port+1); /* Read data bits */ if (bits&PE) data=data|1; /* Shift in '1' if bit set */ } return (data); }