Last year I bought a Willem EPROM programmer board from Sivava. It’s basically a cool little board with various sockets for plugging in EPROM/EEPROM/Flash/etc chips for reading/erasing/writing. Apparently it can even program some AVR microcontrollers. I have the PCB50 version of the board.
Here’s the deal. It has a USB port, but it’s only for supplying power. All communication goes through the parallel port. As everybody should know at this point, the parallel port is on the way out. No, scratch that. The parallel port is long gone. I had to use a really old HP Pavilion with a Celeron running Windows 98 to do anything with it. The programmer worked great, and I was able to fix a computer’s BIOS chip that I had messed up while trying to hack its BIOS.
Let’s fast forward to over a year later (a.k.a. now). I have a homebuilt PC with an Intel DX58SO motherboard and a Core i7 CPU, running Windows 7 Ultimate edition, 64-bit. The DX58SO literally has no legacy peripherals, other than a single PCI slot. It has no PS/2 ports, no parallel port, no serial ports, and no standard IDE ports. It does have a variety of types of PCI Express slots, though.
I recently bought a sweet PCI Express 1x card with four serial ports and a parallel port from Newegg. (Note: Newegg’s product specs lie about this card — the parallel port does not support EPP or ECP mode, according to a sticker on the box, even though Newegg says it does). I remembered that I had my programmer and decided I totally needed to get it working in Windows 7.
Easier said than done.
It’s difficult enough to get low-level legacy stuff working in Windows 7, but when you’re using the 64-bit edition, a lot of older stuff breaks even more. Also let’s remember that add-on parallel ports do not get mapped to the standard I/O addresses for parallel ports (0x378 and 0x278), but instead some other random address (mine is at 0x3000). I tried running the software that came with the board, but it just gives me errors and actually won’t let me exit without forcing it to quit from the task manager.
Let’s go on a Google adventure. Google lesson #1: sometimes when you’re looking for info about Windows 7 64-bit, you can find very useful stuff when you search for Vista 64-bit (or XP 64-bit) instead. My first search was willem vista 64-bit.
The second result was a digg posting titled Willem Eprom for Vista and 64bit XP. The linked page is a forum posting at a forum called onecamonly.com. The post is by the admin of the site, and he mentions to install software called TVicPort and then a modified io.dll file. The first comment on the digg posting was by a user named rabitguy, who said he had a Willem board working on Windows 7 64-bit with tvicport and iodllwrapper.
So I kept seeing this io.dll and iodllwrapper stuff. What exactly is it? Let’s Google for “io.dll”.
The first result is to a homepage for io.dll. Basically, it explains that it’s a library allowing direct port access from several different Windows versions. Awesome! Except it doesn’t mention Windows Vista or Windows 7, or anything 64-bit at all. Crap. Well, I looked in the installation directory for the Willem software that came with my Sivava programmer board, and sure enough, in C:\Program Files (x86)\EPROM50, there’s an evil file named io.dll. So that’s why it doesn’t work.
So anyway, I searched for iodllwrapper, deciding to follow the advice of rabitguy. The first result is to a forum posting on an Amiga message board. I did a search on that page for “Willem” and found a posting by Toni Wilen who wrote a 64-bit-compatible io.dll wrapper which depends on TVicPort and uploaded it as an attachment to the forum, called iodllwrapper.zip. He even included the source code. Aha! So I think I get it. He wrote a DLL that provides all the functions that io.dll would provide, except rather than implementing the raw functionality himself, he forwards the relevant function calls to TVicPort, which handles all the low level stuff (in a manner that works on 64-bit operating systems!). Actually it’s a pretty genius idea. So I downloaded his DLL and tried it out, replacing the stock io.dll file that came with the Willem software with his new wrapper.
I crossed my fingers and opened the programmer software. Awesome! I no longer got a bunch of weird errors when the program opened! I’m pretty sure Toni’s DLL would have worked great, but there’s a problem in my case. I don’t have a built-in parallel port, so my parallel port is at a non-standard I/O address (0x3000). The Willem software only lets you choose from a list of three standard I/O addresses where built-in parallel ports would appear.
Ugh! So I was stuck again. At this point I was about to throw in the towel. But first, I thought about it and came to the conclusion that I can’t be the only one with this problem. So I searched for io.dll willem address.
The first result this time was Ben Ryves’ Remapped IO.DLL. So someone else had the exact same problem! Ben also wrote an IO.DLL wrapper (and he included his source code, too!). His solution is to add an additional file called io.ini into the same directory as io.dll. You put the I/O address of your parallel port into that file (so my io.ini file would contain one line — 0x3000), and set the Willem software to use LPT1. The wrapper DLL looks for any I/O reads/writes in the LPT1 range and remaps them to actually occur at the address specified in the io.ini file. This is exactly what I needed!
It uses another DLL called inpout32.dll to do the dirty work. Actually, Ben’s site very nicely describes everything his DLL does, so I won’t go into any more detail about it.
Well, it turns out that his DLL didn’t work for me, either. It seems that it’s just not compatible with 64-bit Windows 7, at least in my experience. I just could not get it to work. The Willem software would not detect the connected board. I looked at the homepage for inpout32, and apparently there is a 64-bit version, so maybe if I had fiddled long enough I could have gotten inpoutx64 to work, but at this point I actually had an idea of my own, after looking at the source code that Ben included for his DLL.
I knew from everything I had read that Toni’s 64-bit-compatible io.dll wrapper using TVicPort did work. All it was missing was the remapping. So I took Ben’s code and modified it to use TVicPort rather than inpout32.dll. (Alternatively I could have added the remapping to Toni’s code.) I only changed a few lines. I just changed the calls to inpout32.dll for reading/writing to use the corresponding TVicPort functions instead, and also added initialization and deinitialization code for TVicPort.
So I compiled it with Visual C++ Express Edition 2008…ran the “Test Hardware” function on the Willem software…and success! It found the hardware! I was stoked, so I grabbed a BIOS chip from an old motherboard I’m not using anymore (Asus A7V133). It’s a SyncMOS F29C51002T. I chose that model in the software, set up the DIP switches correctly, and stuck the chip in the cool ZIF socket on the programmer board. I then read the BIOS from the chip. I looked at the read buffer and it looked good! I saw stuff about an Award BIOS, so it sure looked like it was working. I happened to have a good copy of the same BIOS file from when I had messed with that same chip on the older computer, so naturally I did a diff against them to make sure that the file was read correctly.
It didn’t read correctly. It differed by just a few bytes. It was mostly OK, but mostly is not good enough when you’re reading to/writing from chips that contain computer code and/or data. At this point I decided to sleep on it and think about it the next day. That approach really works well in all aspects of life in my experience. When I had trouble learning to play a piano piece I would sleep on it and the next day it was like my brain had somehow prepared itself ahead of time, and I would play the part I had been struggling with perfectly.
The next day I noticed that the TVicPort driver actually has an option for two I/O port access “modes.” The default mode is hard mode, which is slower, but provides more reliable access to an I/O port if it’s already been opened by a different driver. Soft mode is faster, but has trouble if a port is already open by another driver. On a whim I decided to try out soft mode. I read the chip again, and this time it worked perfectly. I then erased it, wrote the file back, and compared it. Perfect. I did this several times just to make sure I wasn’t getting lucky, and it worked every time.
So either I got really unlucky on my first try with hard mode, or using soft mode fixed it. I don’t know which one is the case, but regardless, I now have my programmer working in Windows 7 64-bit. And this is the end of our Google adventure.
Google can do a lot of great things if you’re willing to sit down and search. And search. And search. I didn’t actually find all this stuff that easily. I tried many different searches, wording things slightly differently. I ended up only showing you guys the search queries I tried that gave me interesting results.
So…thank you to everyone I mentioned in my post. I’ve never met you or even corresponded with you, but you all helped me get this working. Thank you rabitguy, admin at onecamonly, Toni, and Ben. With all of your info I got it working.
So naturally, here’s my io.dll wrapper, based on Ben’s wrapper, along with the source code for it.
Remember, I’m not responsible for any damage done by this software–it’s been tested lightly and seems to work for me, but your mileage may vary!
Download 64-bit remapped IO.DLL wrapper and source code (new version 1.1 which fixes a bug–thanks Paco!)
You will also need to download TVicPort from here.
Install TVicPort, then restart your computer (mine didn’t work until I restarted, and it does ask you to restart). Replace the io.dll file in the Willem software directory (C:\Program Files (x86)\EPROM50 on my computer) with this patched version. Open up the io.ini file, replace the address there with your parallel port’s I/O address (make sure you keep the “0x” before the address or it won’t work), and put it in the same directory you just copied the DLL file to. Set the Willem software to use LPT1 (0x378). If everything is working correctly, you should be able to go to the Help menu and choose Test hardware, and it will say “Hardware present” in the status bar at the bottom.
If you need to compile the modified io.dll for yourself or make modifications, grab TVicPort.h and TVicPort.lib from the TVicPort installation (C:\TVicPortPersonal\Examples\MSVC) and put them in the project directory. After doing that it should compile.
Hope this helps anyone out there, and thanks again to everyone whose information and source code helped me out!
A quick note: To find your parallel port’s I/O address, go into the Device Manager and open up your parallel port. It’s in the Resources tab:
The I/O range that is 8 bytes long (in my case, 3000-3007) is the important one. So prefix the start address with 0x (so in my case, I ended up with 0x3000) and that’s the value you should put in the io.ini file.