PCS500 x64

Since the software does not work with x64(specifically win7) and the device has been discontinued, is there any possible way to get the software source code released so that the users can rework it to be able to use it in x64? At the moment I cannot use the device(and will not buy from Velleman again if this is how they support their products) because I am only in an x64 environment.

I do understand the difficulties in migrating the software but in this cause it should not require much work. The software simply accesses the parallel port using a kernel mode driver which must be written in x64. But this is already done with the inpout32 drivers(which are free). Hence the pcs500 software just need’s to be properly linked to use these drivers(probably a few hours at most with some time programming). I realize that there is not much money involved for Velleman to support discontinued software but it goes a long way with customer satisfaction.

I would be willing to create a whole new interface that I would release for free for x64 if I knew the communications protocol. I read in a thread somewhere that the documents for doing such things were on the CD… which I no longer have.

Will it be possible to get something done so I can use the device in x64 or should I move on?


Sorry - the source is not available regardless it is quite old.
I think it will not be possible to modify the program to utilize the InpOut32.dll.
The problem is that all the communication routines are written in assembly. Here a little code snippet as an example:

[code] asm
push ebx
push esi
push edi

mov     edi,p2      {ES:BX = K   talletusosoite }
mov     esi,edi
add     esi,2*8192    {talletusosoite}
xchg    esi,edi
mov     dx,pr_portti
add     dx,2
in      al,dx
or      al,00000010b     {244 on}
out     dx,al
mov     dx,pr_portti

//**************** update begin ****************
mov	al,11111111b
out	dx,al
mov	al,11111011b    {laskurin askelluspulsi}
out    dx,al
//**************** update end ******************

mov     ecx,4096      {näytemäärä}          

push ecx
mov al,11111111b {BD2 päälle - OE alas, luetaan CH2 ylemmät bitit}
out dx,al

   mov	cl,4
   inc	dx		{dataportti IN}
   in	al,dx		{luetaan A/D-muunnoksen 4 ylintä bittiä}
   in	al,dx
   shl	al,1		{ja siirretään ne ah -rekisteriin}
   shl	ax,cl
   dec	dx		{dataportti OUT}
   mov	al,11111110b	{luetaan CH2 alemmat bitit}
   out	dx,al
   inc	dx		{dataportti IN}
   in	al,dx		{luetaan A/D-muunnoksen 4 alinta bittiä}
   in	al,dx
   shl	al,1		{ja siirretään ne ah:n alimmiksi biteiksi}
   shl	ax,cl		{edelliset 4 bittiä siirtyvät ylimmiksi}
   mov	al,ah		{muunnostulos al:ään}
   not      al
   xor      ah,ah
   mov	ds:[edi],ax			{talletus (mov es:[di],ax {2x inc di)}
   add      edi,4
   dec	dx		{dataportti OUT}

mov al,11111101b {BD2 päälle - OE alas, luetaan CH1 ylemmät bitit}
out dx,al
inc dx {dataportti IN}
in al,dx {luetaan A/D-muunnoksen 4 ylintä bittiä}
in al,dx
shl al,1 {ja siirretään ne ah -rekisteriin}
shl ax,cl
dec dx {dataportti OUT}
mov al,11111100b {luetaan CH1 alemmat bitit}
out dx,al
inc dx {dataportti IN}
in al,dx {luetaan A/D-muunnoksen 4 alinta bittiä}
in al,dx
shl al,1 {ja siirretään ne ah:n alimmiksi biteiksi}
shl ax,cl {edelliset 4 bittiä siirtyvät ylimmiksi}
mov al,ah {muunnostulos al:ään}
not al
xor ah,ah
xor al,inv
mov ds:[esi],ax {tallennus (mov es:[di],ax {2x inc di)}
add esi,4
dec dx {dataportti OUT}
pop ecx
mov al,11111011b {laskurin askelluspulsi}
out dx,al
loop @looppi2
mov dx,pr_portti
mov al,0ffh
out dx,al {käyttöjännite optoerottimelle}
add dx,2
in al,dx
and al,11111101b {244 off}
out dx,al
pop edi
pop esi
pop ebx

Every in al,dx and out dx,al should be changed to function calls to the DLL.
– Any suggestions how to do this modification easily…?
I think the only way is to rewrite all the communication routines code…

Here a link to download the PCS500 documents: box.net/shared/ybz9k9adq4

Thanks for the documentation. I will start working on it ASAP.

As far as the assembly code goes. You should be able to directly recompile the code in x64 with little change(although there are a few potential pitfalls). I’m now sure how you are using in/out in protected mode since these generally should cause a fault(i.e., the hole point of having to use a kernel mode driver). If that code is from some kernel mode driver(I guess it’s from DriverLinx dll or dlportio) then simply recompiling to x64 should take care of 95% of the work. e.g., The “in” instruction is identical in function as are 99% of all other 32-bit assembly instructions(similar how one goes from 16-bit to 32-bit).

In the code you gave, I do not see any problems that will prevent it from being migrated to x64.

geekswithblogs.net/kernelmode/ar … 20340.aspx

This explains a little how to migrate/integrate 64-bit assembly to C/C++. If you use Inpout64 then it should just be a matter of calling the functions, as you have mentioned. Wrap the call to the dll(inpout64) as normal and call it in assembly appropriately.

geekswithblogs.net/kernelmode/ar … 20337.aspx

You can find a lot of details about how to accomplish writing the device driver(which is not needed if you use inpout64 or equivalent).

I believe you are write in suggesting that it is just a matter of converting all the port calls to function calls(that interface with the kernel mode driver). Since I do not know the inner workings of how PCS500 handles the task of hardware communications I cannot help much. I do know from experience that if it is just a matter of reading and writing the parallel port address then it should be quite a simple fix. If you choose to use Inpout64 then you just have to update the communication’s code to call inpout64’s appropriate function. Doing this in assembly requires you to deal with the frame stack(I believe as I haven’t done pure assembly in ages) which is probably the hardest it will get.

I will work on it and get back with you on my findings.

amd.com/us-en/assets/content … Sept24.pdf

BTW, here are some more links:


and more specifically,


Which suggests there are no issues with the 32-bit user mode application(which I believe the PCS500 app is completely usermode and not using some trick to get hardware access) accessing 64-bit drivers. Hence the only thing you have to change on your side is the kernel mode driver that accesses the hardware ports(which I’m assuming is where the snippet of code you posted came from).

If that truly is the case then you do not even have to recompile the PCS500 source code(although there is a performance degradation if you don’t: msdn.microsoft.com/en-us/library/aa489557.aspx).

My suggestion would be to try to recompile the kernel mode driver you are using and see how far you can get. If you cannot compile inline 64-bit assembly then it will have to be moved to a separate assembly file or converted into C/C++(msdn.microsoft.com/en-us/library … 80%29.aspx).


If you are able to give more details on how PCS500 is accessing the hardware(through a kernel mode device driver? dlportio?) then I might be able to help further. If my assumptions are correct, it may be possible to move the all the communications assembly code into the PCS500 user mode application EXCEPT the hardware port access(in/out) and use inpout64 to access the data. This way you can still keep PCS500 in 32-bit and still have inline assembly(virtually no change in the assembly code). Essentially we would move all the unnecessary code outside the kernel mode driver and insert it in the user mode code. In fact, if you choose to use Inpout64 then it will almost become trivial to do. Unfortunately this requires PCS500 to stay in 32-bit mode and have the performance degradation associated with that(which may cause timing problems).

Thank you for all the information and the suggestions how to get the PCS500 running in x64 environment.
The driver driverlinx dlportio is third party software and we have no access to the code to compile it for x64 system.
If it is possible to use the InpOut64 from the 32 bit software this may be the solution.
BTW: this is very interesting: “There is also a x64 version of inpout32 that is compatible on x64 AND (if renamed to DLPORTIO.dll) is compatible with DLPORTIO.”
found here: lcdhype.condense.de/index.php?showtopic=3340

Yes, but how does pcs500 use dlportio? I have tried replacing dlportio with inpout64 with no luck.

Can you paste the code where pcs500 installs the dlportio.dll and calls some functions so I can get some idea of how it is using it? The code you posted earlier seems to imply that dlportio has the communications routines inside it. If this is the case then it is not compatible with inpout64 since inpout64(and 32) is simply a wrapper of the in/out assembly routines.

e.g., If I were going to write a pc scope GUI I would simply write it like normal but when I need to access the parallel port’s data I would call a function that acts exactly like the cpu’s in/out instructions. These functions actually just pass a call to a kernel mode driver that actually executes the in/out routines.

Either the code you posted is from very old PCS500 software that accessed the port’s directly(which later was moved to dlportio) or that code is part of dlportio(you mention that it is third party software but this does not tell me where the code you pasted comes from).

If dlportio is simply wrappers for the in/out instructions then it will be very easy to migrate the pcs500 source code to use inpout64. It is just a matter of updating the dll references(externs) which most likely differ(I haven’t checked). Or, in fact maybe we can just recompile inpout32 and modify the references to match. I haven’t been able to take a look at the differences between dlportio and inpout yet but I’ll try to do that asap. My problem is that I get the error code

“Could not open the DriverLINX driver”

Is DriverLINX dlportio?

driverlinx.com/DownLoad/dnlo … O%20Driver

suggests that it is. If that is the case and dlportio is simply wrappers of the in/out instructions then it should be a piece of cake to get it to use inpout64. I’ll analyze dlportio and see how the exports differ from inpout64 and see if we can’t simply modify them.

Here is the code to load the driver:

if Win32Platform=VER_PLATFORM_WIN32_NT then begin // Driver is in the same directory as the .exe file! DLPortIO1.DriverPath:=ExtractFileDir(ParamStr(0)); // Open the DriverLINX driver DLPortIO1.OpenDriver(); if (not DLPortIO1.ActiveHW) then loaderror:=true; if not loaderror then DLPortIO1.Port[pr_portti]:=Byte($FF); end;

When driver is installed the assembly language “in al,dx” and “out dx,al” work.
If you can grabb the “in al,dx” and “out dx,al” and convert to work in x64 system then it should work… I think.

The InpOut32 /64 uses the DLL function calls.

PachoPecho or VEL255 have you got the 64 bit driver working? I have tried just about everything I can think of trying to get the 64-bit versions of DlportIO.dll and DlportIO.sys to work.

Some other locations for the 64-bit files:
logix4u.net/Legacy_Ports/Paralle … 4_bit.html

Sorry, I have to finish up another business project and haven’t had time. I looked into it a while back and got the documentation to be able to make my own software and driver. It’s relatively easy for the most part but there are a few issues that one has to deal with to make it work which involve transferring the data. I started writing the driver but couldn’t get it to run without crashing my comp. Had to get a virtual machine running and was having problems getting the a disk image converted to vhd(since I didn’t want to install everything fresh).

I need to install XP x64 and use that to develop the driver. Basically it’s pretty simple but probably is going to require the driver to get the data asynchronously(sorta acting as a DMA) so that one doesn’t lose data.

Since I haven’t had to use the scope I haven’t really bothered with it and been focusing on my main project. Not sure if I’ll get into to mess with it or not. (To be honest it’s probably not worth it as it will be easier to just buy a new scope since if I do the driver I’ll want to write my own software interface.)

PCS500.exe now runs on X64 systems. See end of article for details. The given solution should work with all Velleman products connected to a parallel port; PCS500.exe is taken as example here. Moreover, it should work with any other I/O software with compiled-in instructions, like avrdude (tested: yes).

The assembly code, translated to C would be like this

void readsamples(DWORD p2[4096+4096], WORD lptbase, BYTE inv) {
 DWORD*k0=p2;				// was: ESI
 DWORD*k1=p2+4096;			// was: EDI
 outportb(lptbase+2,inportb(lptbase+2)|2);	// enable 74HC244
 outportb(lptbase+0,0xFB);		// Counter Clock
 for (int i=0; i<4096; i++) {
  BYTE b;
  outportb(lptbase+0,0xFF);		// open BD2, enable !OE, CH2 upper nibble
  b=inportb(lptbase+1)<<1 & 0xF0;	// read high nibble of A/D data
  b|=inportb(lptbase+1)>>3 & 0x0F;
  *k1++=(BYTE)~b;			// save sample
  b=inportb(lptbase+1)<<1 & 0xF0;
  b|=inportb(lptbase+1)>>3 & 0x0F;
  outportb(lptbase+0,0xFB);		// another counter clock
 outportb(lptbase+0,0xFF);		// Maximum power supply
 outportb(lptbase+2,inportb(lptbase+2)&~2);	// disable 74HC244

Weird code, to put the samples into two distinct DWORD arrays instead of leave them interleaved compatible to 8-bit stereo sound data.

The first attempt

To get InpOut32.dll to work, a debugger-like extension has to be introduced that puts the scope software as debuggee into a sandbox with hardware breakpoints to the I/O base address. It’s interesting whether WoW64 will emulate this feature too. USB-based LPT emulators can benefit from knowledge of this basic routine because the target for the data is known and can be patched after reading all the 4096x2 samples.

It seems that (at least some) I/O instructions are not implemented as native assembly instructions inside PCS500.EXE but by calling DLPORTIO.DLL’s entries DlPortReadPortUchar() and DlPortWritePortUchar().

Unluckily, PCS500.EXE tries to open a “\.\dlportio” device which fails when using InpOut32.dll. I’m working on a solution to cope with this problem.

It’s correct, DriverLINX is the same as dlportio. It is the Service Name (FriendlyName) for dlportio.sys.

You may crash PCS500.EXE while running by executing this command:

net stop dlportio

In this case, an exception will be thrown and catched by a custom messagebox.

The trial debugger software did run but had some disadvantages:
[li] Requires the PCS500.EXE to be patched so it “thinks” running on Windows 9x/Me[/li]
[li] Performance is incredibly poor[/li][/ul]

Some thought about better solutions for the coders

It would be MUCH BETTER when Velleman changes its source code to rely on InpOut32.DLL instead of DlPortIo.dll.
[li] Runs in Win64[/li]
[li] No installation and initialization code at all (it’s all “outsourced” to InpOut32.dll)[/li]
[li] No need for LoadLibrary / GetProcAddress[/li][/ul]
[li] “in” and “out” assembly instructions must be replaced by Inp32() / Out32() function calls[/li]
[li] Somewhat slower data transfer rate[/li][/ul]

The BEST way is when Velleman splits their PCS500.EXE into the core .EXE and a hardware access DLL with the following entry points:
[li] SetData(WORD portbase, LONGLONG bits) // fill shift register chain[/li]
[li] GetData(WORD portbase, BYTE*data) // get sample buffer data, 8192 bytes[/li]
[li] GetStatus(WORD portbase) // query status lines to see whether sampling is complete[/li][/ul]

A quite good working solution, suitable for end-users, with no patch at all

Now I found a clue to install a process-wide exception hook in front of the stack-based exception handler, the AddVectoredExceptionHandler() function. This enables handling of exceptions without context switching. However, exceptions are still thrown massively, because IN and OUT instructions are 1-byte-opcodes and cannot be useful patched to another code. A test routine doing 1000000 IN instructions revealed 7 seconds for exception catching, and more than 30 seconds for context switching (between debugger and debuggee, as fallback needed for Win2k ONLY where no AddVectoredExceptionHandler() API exist).

So I modified the (my) InpOut32.dll to install exactly this exception handler on startup. Moreover, it contains a rundll32.exe-callable entry point to inject this DLL (i.e. itself) into the process. This trick enables the possibility to fake the Windows version without patching the .EXE image. As a net result, PCS500.exe works on Win64 now, with acceptable performance, using the following procedure:
[li] Download www-user.tu-chemnitz.de/~heha/vi … pout32.dll[/li]
[li] Rename it to DlPortIo.dll and overwrite the same file name in the PCS500.exe directory[/li]
[li] Create a shell link with this command line: “rundll32 DlPortIo,CatchIo PCS500”[/li]
[li] Execute it with raised privilege, and be happy![/li]
[li] DlPortIo.sys is useless [i.e. cannot be loaded on X64 ever] and can be removed.[/li][/ul]

[color=#4040BF]Under the hood[/color]

[li] The rundll32.exe loads the renamed InpOut32.dll and calls the entry point CatchIoW with the command line argument L"PCS500"
In case you have started the 64-bit version of rundll32.exe, loading the DLL will fail silently, and the 32-bit version of rundll32.exe will automatically launched by that 64-bit process, which then will not fail to load that 32-bit DLL.[/li]
[li] The CatchIoW entry creates a suspended process using the PCS500.exe image. It is important not to be a debugger, to prevent costly exception routing between debuggee and debugger.[/li]
[li] A remote thread is created that loads the renamed InpOut32.dll into the PCS500.exe process. This is called DLL injection. This injection is the reason why the DLL must be of same bitness as PCS500.exe, i.e. 32 bit.[/li]
[li] Its initialization routine unpacks, installs, and loads the signed inpoutx64.sys driver. This step requires administrative privilege. As there is no known I/O access map in X64 (the so called “long mode”), no clean driver can ever make I/O address space transparent to user-mode applications. Therefore, an exception mechanism has to be used, see next step. As a side effect, InpOut32.dll can re-route to unusual port addresses and some USB devices. The necessary initialization and device/address detection is done at this DLL startup.[/li]
[li] The initialization routine installs the process-wide exception filter routine.[/li]
[li] Another remote thread is created that changes the address to the kernel32.dll routine GetVersionEx(). The faking routine reports that the process is running on Win9x/Me. This is called API hooking. The reason for that second thread is that API hooking should not occur when the DLL is loaded and used regularly {by LoadLibrary() or static binding}.[/li]
[li] The PCS500.exe main thread is released and runs. It will “detect” Win9x/Me and doesn’t try to install+load DlPortIo.sys.[/li]
[li] PCS500.exe loads DlPortIo.dll using LoadLibrary(). This call does nothing as this library is already injected.[/li]
[li] PCS500.exe collects all entry points of DlPortIo using GetProcAddress() - for nothing but detecting that there are no NULL pointers. None of these entries are used. All this behaviour comes from the DlPortIo.dpr Delphi unit, which is open-source and obviously used by Velleman without changes.[/li]
[li] Then, communication with hand-made assembly IN+OUT instructions are executed. Each such instruction will raise an exception which goes to kernel mode, I believe Int13 (general protection fault, #GP). The handler there detects that it’s by a privileged instruction, and delegates handling to ntdll:KiUserExceptionDispatcher, which in turn executes the installed process-wide exception filter first (before the stack-based handlers using try/except).[/li]
[li] The exception filter (which resides in the renamed InpOut32.dll) in turn detects that it comes from an IN or OUT instruction. The faulting instruction is skipped, and the inpoutx64.sys driver is called using DeviceIoControl() to make the actual operation. For IN instructions, the register AL is modified in the process’ context. Then, the exception handler returns with information “Do not seek further, the exception is handled”.[/li]
[li] To save time, contiguous series of equal I/O instructions, originally inserted to create some µs delay, are skipped automatically. The exception handling itself consumes several microseconds.[/li]
[li] After this lengthy detour, the next assembly instruction is executed.[/li][/ul]

[color=#404000]Can dlportio.sys ever be made compatible to X64?[/color]
This is not entirely cleared. The AMD64 architecture supports an I/O permission map in the TSS (Task State Segment) compatible to the IA-32 architecture. While it is possible to a kernel mode driver to access and to patch this table, there are some annoyances:
[li] There is no API to access the I/O map[/li]
[li] The map is no more task specific. (This AFAIK applies only to DOS boxes and Win16 emulation in 32-bit Windows versions.)[/li]
[li] The I/O permission map is AFAIK set to zero length, therefore, space must be allocated and the TSS must be moved somewhere which may disturb Windows heavily[/li]
[li] A kernel code guard watches for changes at critical memory areas as IDT (interrupt descriptor table) etc. If it detects a change, a bluescreen will end your Windows session some seconds or minutes later.[/li]
[li] There are tools to defeat the guard, and Windows updates that defeat the tools. At the end, Microsoft will win.[/li][/ul]
As a conclusion: Theoretically yes, practically at least experimental, but the solution above is much more safe.

[color=#804000]What about USB adapters?[/color]
Unluckily, some disassembly of PCS500.exe revealed that the assembly routines are implemented multiple times and somehow more complicated than explained at the top of article. Therefore, emulating these routines in USB devices is almost impossible, and it’s much better to write a tailored (i.e. new) scope software for the PCS500 device rather than twiddeling with the executeable by Velleman somehow.
I wrote a suitable universal scope software some years before, see http://www.tu-chemnitz.de/~heha/hs/. It features a standard plugin for soundcards, a scaleable screen, and in-screen trace scaling/shifting operations with no valuable-screen-space-consuming control knobs. But for writing a suitable plugin, I need a real PCS500 device lent by someone.

Can someone reply performance reports? I have no PCS500 hardware to check.

henni, 130902 - 131209

Hi, I have tried your method and cannot get the pcs500 software to recognize the device.

I downloaded your linked inpout32.dll and renamed it to dlportio.dll in the pcs500 software dir overwriting the original dlportio.dll.

I ran it using “rundll32 DlPortIo,CatchIo PCS500” (I had to use the exact dir for dlportio or I would get errors).

The software loaded. I tried all various combinations of ports and normal and slow speeds but the software never recognized the device.

I’m trying various ports to see if I can get it to work. I’m using an expansion parallel port card that may be the problem…


I was able to get it to work. When trying the various ports I heard the scope click like it usually does when working. I still got the dialog box saying that it wasn’t working but when I clicked “run” I got some traces. This only happened when using slow mode.

Performance is pretty bad but I guess useful in some cases. The software is using 25% cpu and the gui lags significantly(about 3-5 seconds). Switching over to normal communications doesn’t change anything AFAIK and the scope stops working after a while and shutting down when it’s broke gives an access violation in dlportio.dll trying to read really low addresses.

Is it possible that the inpout32.dll is not working efficiently and can be improved? For the most part it is working as I can alter the waveforms.

[quote=“henni”]Can someone reply performance reports? I have no PCS500 hardware to check.

Great work BTW! The performance of the software using your method seems to run at about only 10%. Instead of realtime display of the waveform it takes about 3-4 seconds for it to show the result, similar to how the original software would work when running at a very low timebase.

If it could be improved then it would definitely be the solution.

You would think Velleman would take a few minutes out of their day to update the software, can’t be too hard, or at least release the source code but I guess they don’t want repeat customers. Why invest in velleman if when they decide the products dead your stuck out in the cold? I specifically won’t buy any more Velleman products because of my experience with the PCS500. It’s not a bad piece of hardware but the lack of proper software makes it very difficult to use.

There is a new solution: tu-chemnitz.de/~ygu/hs/giveio64.zip

It activates the still-available but underdocumented Input Output Permission Map IOPM, then pcs500.exe will work at its original speed!
The compareable kernel debugger commands were:
eb @gdtr+@tr+1 20
eb @gdtr+@tr+1 20
This extends the TSS of both processors by 8 KByte. (The TR register contains 0x40.) Windows (Vista 64) seems to reserve the memory needed beforehand. It’s zero-filled and therefore enables all I/O addresses.

The driver is compatible to dlportio.sys. No need for disabling PatchGuard due to a nice trick and some luck. Moreover, the driver is digitally signed. See readme.txt for further instructions.

[quote=“henni”]There is a new solution: tu-chemnitz.de/~heha/hs/giveio64.zip

It activates the still-available but underdocumented Input Output Permission Map IOPM, then pcs500.exe will work at its original speed!
The compareable kernel debugger commands were:
eb @gdtr+@tr+1 20
eb @gdtr+@tr+1 20
This extends the TSS of both processors by 8 KByte. (The TR register contains 0x40.) Windows (Vista 64) seems to reserve the memory needed beforehand. It’s zero-filled and therefore enables all I/O addresses.

The driver is compatible to dlportio.sys. No need for disabling PatchGuard due to a nice trick and some luck. Currently, the driver is not signed. See readme.txt for further instructions.[/quote]
Hello, could someone write a step by step how to for this solution? Pleeeeease! )))


Please help me with this tested solution. I can not get my pcs500 running. It drops the message “please run install_drv.exe to install the driver”.


[quote=“aant”]I can not get my pcs500 running. It drops the message “please run install_drv.exe to install the driver”. [/quote]RTFM the readme.txt!!!

First, unpack giveio.sys to any persistent (i.e. non-temporary and non-removable) location and check whether the digital signature of that file is valid. (Right-click on file, choose “Properties”, and select the “Signatures” tab.) If not, you have a problem with your Windows certificate store you have to solve somehow first.

Then, again, for the deaf: Open a “cmd” command line window, and enter

sc create dlportio type= kernel binpath= <full_path_to_giveio.sys>The spaces after “=” are REQUIRED by sc command. The TAB key helps you to enter the <full_path_to_giveio.sys>.

Should emit SUCCESS.

Then enter

sc start dlportioShould emit

SERVICE_NAME: dlportio TYPE : 1 KERNEL_DRIVER STATE : 4 RUNNING (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0 PID : 0 FLAGS :Now you can start the PCS500 application and close the cmd window in any order.

Hello Henni,

Thank you for your help. Now it works. I had to clean-up registry first and reboot, then perform what you wrote and then it starts to work.

I’m not deaf and this forum is not software development board.

Best regards,

Hello !

In september 2015, Dr.Sqaer asked to have a step by step how to.

Here, I proposed a step by step how to using the dlportio renaming solution of henni. Sorry if it is too detailed.

  1. PClab2000SE installation

Download PcLab2000SE_v4_05_setup.zip from velleman website.
Unzip it and copy pclab2000se_v4_05_setup.exe to C:\

Execute PcLab2000SE_v4_05_setup.exe

When the setup will ask you for the « destination location », remove « Program Files (x86)\Velleman\ » from the proposed choice, to have only :


Terminate the installation with the other proposed options.

  1. Deletion :

In the folfer C:\PCLab2000SE, delete both files :

  1. Download the file www-user.tu-chemnitz.de/~heha/h … -h%23s.zip to C:\

Unzip it keeping the folders structure.

In the folder c:\inpou32-h\Release , copy the file INPOU32.DLL to C:\PCLab2000SE

In C:\PCLab2000SE rename now INPOU32.DLL to DLPORTIO.DLL

  1. Batch file :

In C:\PCLab2000SE create a batch file SOL.BAT with the command line :

rundll32 c:\pclab2000se\dlportio.dll,CatchIo c:\pclab2000se\PCS500.exe

Please note in the « CatchIo » word, the letter # 6 is « i » and not « L »

  1. Execute SOL.BAT with raised privilege. Normally, it will work.

  2. Other little information :

The henni solution works with :

  • a native classical parallel port, with LPT port address 378

  • Pciexpress card for addition of parallel port , with LPT port adress indicated by win7 in the system properties

  • win7 guest hosted by VirtualBox running on linux host computer.
    The LPT port adress is the adress given by VirtualBox, and can be 378, even if the host computer is using Pciexpress card for parallel port

Best Regards,



Here is my experience with PCS500 connected to a parallel port on a PCIe card. PC is running Win7x64, and I patched the system as per Henni’s procedure (thanks).

  1. I managed the scope to connect to LPT1, addr 378. No other combination of LPT/addr ever worked.
  2. Success rate of connection is about 70%. In the other 30% of cases it simply rejects to establish connection. Retrying shell script is often enough to succeed, without need to reboot the PC.
  3. Speed is always VERY SLOW, with lots of latency delays. I can only effectively use the transient mode, if transient is really slow (if changes take longer than 0.5s). “Normal” oscilloscope mode is not realistic at all.
  4. I checked back the instrument on an old PC with Win98. It works flawless.

As a result, the setup PCS500+Win7x64 is not useful, not even at hobbyist level. It’s a pity that Velleman is not providing a solution for a combination of HW (PC+scope) that could deliver the expected performance. I feel very reluctant to trust upcoming Velleman instruments, if forward compatibility is not a priority.


For everyone, who wants to use PCS500 on Windows 10 Pro x64 (I don’t try it on another versions).
You need computer with motherboard with native LPT port or PCIexpress card

First thank you very much to Henrik Haftmann. He developed functional 64 bit replacement driver for giveio.sys and dlportio.sys In readme he has a note, that it is not working in Windows 10 and he get blue screen, but in my case it is working without issue, so the problem is probably on his system.

So this is the manual:

  1. download latest version of [color=#0000FF]PCLab2000SE[/color] from Velleman site.
  2. download [color=#0000FF]giveio64.zip[/color] from haftmann#software freeware list site.
  3. install PCLAB2000SE to the folder c:\PCLab2000SE. Do not install any drivers, only this software.
  4. copy giveio.sys from downloaded zip file to the folder c:\PCLab2000SE\
  5. run Command line (cmd) as adminitrator
  6. in cmd windows run command [quote]sc create dlportio type= kernel binpath= c:\PCLab2000SE\giveio.sys[/quote]
  7. in cmd windows run command [quote]sc start dlportio[/quote]
    the output should be as this:
    SERVICE_NAME: dlportio
    WIN32_EXIT_CODE : 0 (0x0)
    SERVICE_EXIT_CODE : 0 (0x0)
    CHECKPOINT : 0x0
    WAIT_HINT : 0x0
    PID : 0
    FLAGS :
  8. run the PCLab2000SE for PCS500 and in Options -> Hardware Setup choose the address of your LPT port. You can find in in Device manager -> Ports -> Printer port properties