But now there's inpout32.dll -- which works on Win98SE, Win2K and WinXP. This DLL provides hardware I/O to your computer's parallel port.
Using Borland's Free C++ Command-line Compiler, I wrote a test program which demonstrates I/O to a printer port using inpout32.DLL -- Now you can do port I/O directly from a C program, and compile everything in a DOS console.
NOTE: Test1.c uses pointer function calls.
To use direct function calls, try leaving the code as it is,
and placing two more small "wrapper" functions with different names,
into the original file, before main(). For example,
short Input (short portaddr) { return (inp32)(i); } void Output(short portaddr, short datum) { (oup32)(portaddr,datum); }You can name these functions, 'Input' and 'Output' to whatever you want...
package hardware.jnpout32;
import jnpout32.*;
Note that the same effect can be achieved by using Jnpout32reg_v10, and follow a similar procedure as above, putting everything found in folder 'ioTest_reg' in a development folder of your choice. Then, replace ioTest.java with your application, and be sure to use the declaration
import hardware.jnpout32.*;
For bigger applications with a deeper hierarchy of source code, the solution is to use Jnpout32reg_v10, but this does requires a C compiler to rebuild the DLL with the exact relative path to the 'jnpout32' folder.
I think Jnpout32reg_v10 is more versatile in the way it is done, and fundamentally demonstrates the nature of solving a problem by rebuilding a custom DLL for a particular JNI application. After taking some time to study and understand the mechanism of how this DLL uses the RegisterNatives() JNI method, you will probably agree.
For more detailed explanations, download both of them and look in the README files.
Also, you can refer to an
online version of the book I used as a reference during
my development of the Jnpout32reg_v10 project:
http://java.sun.com/docs/books/jni/
(Java Native Interface: Programmer's Guide and Specification)
Signed or unsigned really doesn't matter for an I/O address, or for a
short range of addresses which don't cross the 32767 boundary. When doing
arithmetic on an I/O address within a device's address space, it shouldn't
involve anything more than adding an offset of 15 or less (typically
no more than 7) to the I/O base address. And yes a short is a full 16 bits;
all 16 bits are passed in the call. This should present no problem to access
devices at a higher I/O address; for example, ((short) 0x9500).
There have been some questions about using a Java 'int' for convenience,
but the wrapper uses 16-bit 'short' because the DLL uses 16-bit 'short',
and in my assessment I say modifying the DLL is a poor solution.
For those who insist on programming a 16-bit I/O application with 32-bit 'int',
here are some suggestions.
Port_Base_Addr = (short) 0x9500;Note that the compiler will keep the lowest 16 bits only.
int Port_Addr = 0x10AC00; Port_Base_Addr = (short) Port_Addr; /* Port_Base_Addr now contains 0xAC00. */
// wrap ParallelPort output method /* public void output(short port, short value) */ public void output(int port, short value) { /* pp.Out32(port, value); */ pp.Out32((short) port, value); } // wrap ParallelPort input method /* public short input(short port) */ public short input(int port) { /* return pp.Inp32(port); */ return pp.Inp32((short) port); }
When casting such a (signed) short to a (signed) int, usually a mask
is desirable.
int X = (int) input(Port_Addr); X = (X & 0xFFFF);or alternatively
static const int mask = 0xFFFF; int X = (mask & (int) input(Port_Addr));
Don't forget to visit My Home Page for other things of interest!
EOF