Parallel Port Access Under Win32 C++
Platform: PC Windows 32 Application
Language: C++ Compiler: MSVC++ 6.0 API:DirectX 7.0
I just ran into a problem with a project of mine, hope someone can help. I am writing a game that will make use of an electronic device that is connected to the parallel port. I needed to be able to use Data lines 0-7 as sources of +5v to drive some led''s. This was no problem for me while testing under a console application as I used the _outp(0x378, [int/hex value]) function to control the data lines. Upon moving the program to a win32/directX environment I was dismayed that this function causes the window to collapse and the application to hault. I assume that this is because the function only works under DOS and console apps. So my question is, how can I gain control of the data lines of the parallel port under a win32 app. Does DirectX contain contexts for a printer device? I know that I can create different apps using the wizard in MsvC++ but i can''t throw away the rest of my game. This is how it worked under
Console app:
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#define DATA 0x378 // Address of parallel port
void main()
{
_outp(DATA, 10); // outputs a binary 10 on data lines
// under Borland this function is
// outport(DATA, [int/hex value])
}
so the above would put 00001010 on the data lines and drive tha anode side of my 8bar led display with +5v.
It''s likely that a console prog would collapse on NT as well, due to more robust restrictions on accessing ring0 from ring3. Look into GDI for printer device contexts. Also take a look at the winio dll at internals.com for accessing the parallel port. In the worse case, you might have to write a small device driver of somekind.
I´m having the exact same problem zenassem. Magmai, How do I write a driver? Can you point me to any link? Thanks!
Writing a device driver means getting the Device Driver Kit specific to the target platform - W95, W98, WME, WNT, W2K, WXP - each of them are large, but not as large as the PSDK. I have a copy of the DDK for W2K. It even comes with a compiler! cl.exe because you can''t use the MSVC compiler. Most of the DDK consists of special headers for kernel mode. There are a couple of interesting newsgroups related to the topic.
But you don''t need to do any of that. The winio dll will let you access the parallel port with a command as simple as "GetPortVal(0x378,&dwPortVal,4);". Internals.com
But you don''t need to do any of that. The winio dll will let you access the parallel port with a command as simple as "GetPortVal(0x378,&dwPortVal,4);". Internals.com
IIRC, in NT you can access the parallel port using CreateFile("\\\\.\\LPT",...). Look on MSDN.
You can probably use the parallellport pretty much as you would a COM-port.
CreateFile("LPT1" . . . . .) or whatever port it is.
GetCommState(. . .)
SetCommState(. . .)
WriteFile(. . . .)
CloseHandle(. . . .)
Just fill in the dots with a trip to MSDN.
CreateFile("LPT1" . . . . .) or whatever port it is.
GetCommState(. . .)
SetCommState(. . .)
WriteFile(. . . .)
CloseHandle(. . . .)
Just fill in the dots with a trip to MSDN.
quote:Original post by Anonymous Poster
You can probably use the parallellport pretty much as you would a COM-port.
CreateFile("LPT1" . . . . .) or whatever port it is.
GetCommState(. . .)
SetCommState(. . .)
WriteFile(. . . .)
CloseHandle(. . . .)
Man, wouldn''t that be nice?
Try searching MSDN for it...
quote:Anonymous Poster
IIRC, in NT you can access the parallel port using CreateFile("\\\\.\\LPT",...). Look on MSDN.
Did a quick search, hoping you were right... 0 hits
The only information I found on MSDN last time I checked for this, was info about making a driver to do what you needed. From what I''ve gathered, you have to handle the ISR for the port, since parallel transfers are unbuffered (unlike serial).
I wasn''t that hot on the project, and dropped it when it started to get hard...
I''d be happy to hear (and see) contrary information...
Another alternative, is to search for an NT driver that provides a serial-like interface.
I´ve found a driver on the the internet for free. The webpage is: http://www.driverlinx.com//DownLoad/DLPortIO.htm?ID=1027728744560 . I haven´t tested it yet with the multimeter, but I´m pretty sure it works. Oh! I tested it with a DX App (making a couple of functions calls inside the main loop) and the program didn´t crash at all.
Hey guys/gals
Thanks for the replies. I will check out LessBread's suggestion as well as Ignacio's link today. I did check out the MSDN disks, but I didn't find anything promising with regard to LPT1, it seems that I would be better off using the serial(COM) port intstead. I tried using "outfile" and this did send a print job , that coincidentally errored, to the default printer device (Generic IBM Text Only). This obviously did not work since the driver is not compatible and I haven't done anything with the electronics to send back as ready to RCV or ACK signal.
Additionaly,
for the time being I decided to Write [Virtual Parallel Port Emulator and 10-bar Led] Classes. Hence my next question. the _outp() function was great because it converted my decimal "decval" to binary and set the corresponding bits on LPT1. So as 'decval' increased the the function would automatically give me a binary counting clock on the LED display.
How should I model these objects in my class, and how can i convert the decimal index to binary for the pins.
assume:
int decvalue=0 ; decimal value initalized will increment to 128
for simplicity lets say that the Class acts more like a struct and everything is public and assume that other variables are global. My first bad idea was to model the data ports in array; short int port[8] = {0,0,0,0,0,0,0,0} // data line 0-7 set to off
Then I index into this array to change the bits, which eventually drives the (sprites showing the value of the ports) on the display. This obviously takes more memory than bit fields
, but it works. The problem is: decvalue will be a decimal number staring at 0 and incrementing to 128. What is the best method to take the decimal value and change the corresponding array elements to give the binary equivalent. I have a brute force method, but it just looks ugly.
It contains ints that hold the binary place holders.
eg. 1,2,4,8,16,32,64,128
I use an 'if else' to first check if decval is = to one of these
then set the bit that corresponds to the index. Next I look into the array checking to see if decval is less than each place holder. eg. if (decval<128){}; if(decval<64) etc. and when this is true I perform a division, set the current bit, and repeat this process until the decval = 0. (There are other steps like adding the values and such but you get the idea).
There has to be an easier way. Should I do a recursive solution? Is there a function that can handle this for me? Is my structure completely wrong? Should I use bit fields? If so, How can access and change each bit in the field to correspond to decval?
[Please dont' suggest that I create 128 arrays to hold the binary equivalent] My firend actually suggested this.
[edited by - zenassem on July 29, 2002 9:30:29 AM]
Thanks for the replies. I will check out LessBread's suggestion as well as Ignacio's link today. I did check out the MSDN disks, but I didn't find anything promising with regard to LPT1, it seems that I would be better off using the serial(COM) port intstead. I tried using "outfile" and this did send a print job , that coincidentally errored, to the default printer device (Generic IBM Text Only). This obviously did not work since the driver is not compatible and I haven't done anything with the electronics to send back as ready to RCV or ACK signal.
Additionaly,
for the time being I decided to Write [Virtual Parallel Port Emulator and 10-bar Led] Classes. Hence my next question. the _outp() function was great because it converted my decimal "decval" to binary and set the corresponding bits on LPT1. So as 'decval' increased the the function would automatically give me a binary counting clock on the LED display.
How should I model these objects in my class, and how can i convert the decimal index to binary for the pins.
assume:
int decvalue=0 ; decimal value initalized will increment to 128
for simplicity lets say that the Class acts more like a struct and everything is public and assume that other variables are global. My first bad idea was to model the data ports in array; short int port[8] = {0,0,0,0,0,0,0,0} // data line 0-7 set to off
Then I index into this array to change the bits, which eventually drives the (sprites showing the value of the ports) on the display. This obviously takes more memory than bit fields
, but it works. The problem is: decvalue will be a decimal number staring at 0 and incrementing to 128. What is the best method to take the decimal value and change the corresponding array elements to give the binary equivalent. I have a brute force method, but it just looks ugly.
It contains ints that hold the binary place holders.
eg. 1,2,4,8,16,32,64,128
I use an 'if else' to first check if decval is = to one of these
then set the bit that corresponds to the index. Next I look into the array checking to see if decval is less than each place holder. eg. if (decval<128){}; if(decval<64) etc. and when this is true I perform a division, set the current bit, and repeat this process until the decval = 0. (There are other steps like adding the values and such but you get the idea).
There has to be an easier way. Should I do a recursive solution? Is there a function that can handle this for me? Is my structure completely wrong? Should I use bit fields? If so, How can access and change each bit in the field to correspond to decval?
[Please dont' suggest that I create 128 arrays to hold the binary equivalent] My firend actually suggested this.
[edited by - zenassem on July 29, 2002 9:30:29 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement