Link to home
Start Free TrialLog in
Avatar of biroadam
biroadam

asked on

Writing device driver in Delphi

I want to write a very simple device driver for Windows 95, and I'm not sure whether I can do it using Delphi.

If I can do it, please tell me how (there is, for example, 'DLL' project type, but no 'VXD').

If I can't do it, please tell me what possibilities do I have? Without buying expensive programs, if possible.

The device driver should be VERY SIMPLE. It should be able to read/write a few I/O ports, and it should be able to handle an interrupt. The rest of it I will do from a DLL.
Maybe there are standardized VXDs for such simple tasks?
Avatar of Mohammed Nasman
Mohammed Nasman
Flag of Palestine, State of image

Hello

  there's two question open for the VXD, you can look there and see the links posted
there's only one site I saw talking about creating VXD in delphi, here's the link
http://www.adwin.ru/dinfo/eng/materials/vxd.phtml 

and here's the questions for this subject

http://otnxchange.experts-exchange.com/jsp/qShow.jsp?ta=delphi&qid=20144841

http://otnxchange.experts-exchange.com/jsp/qShow.jsp?ta=delphi&qid=20148905

Mohammed
Avatar of teacher_mod
teacher_mod

Comments which were irrelevant and offensive have been removed form this question by:

teacher_mod
Community Support Moderator
Experts-Exchange
teacher_mod@experts-exchange.com
Hi biroadam...

To my best knowledge I guess you can't write a device driver using Delphi. One of the most popular ways is using C, C++ or probably assembler.

Best regards,
Manuel Lopez (lopem)
There is a free piece of software that will give you access to ports and ram in W98 and NT
http://www.internals.com/utilities/winio.zip

I have a unit to make it easy to work with using delphi if you need it....

But I know of no free way to handle interrupts... I did see a package that
if I remember correctly does allow working with interrupts...but it was not free.. it was at a site called something like entech taiwan... maybe someone else remembers where this site is located :-)
Gwena, I think you mean TVicHW32 and TVicPort
http://www.entechtaiwan.com/tools.htm

 if you are looking in the other questions you will find this site and other one
Avatar of biroadam

ASKER

Hi everybody!

mnasman:
Thank you for the excellent links; unfortunately I work with Delphi 4 and 5, so the first link is quite unusable for me. The TVicHW32 is interesting, and if it would be for free, I would say that it is just what I want.
Anyway, it will be enough for a time, then I'll see.

lopem:
I would be interested also in some free vxd generator utility or multipurpose device driver.

Gwena:
Unfortunately the IRQ handling is a key problem, so I don't see better solution yet than the TVicHW32.


A question for everybody:
It seems that I don't understand the vxd philosophy. I thought that a Windows program can't access the ports without using an installed driver, but I have the feeling that I was wrong. The TVicHW32 program can access all the ports and interrupts without installing any drivers, just simply loading a vxd file. I don't see the protection here. I was able to kick out the VGA card writing on its I/O ports without any problem.
The other thing I don't understand is that I expected to see the device in the device manager, with the possibility to specify the I/O range, IRQ number etc. But the TVicHW32 doesn't appear as a device in the device manager.
What should I do to transform a vxd into a normal device driver?

Best regards,
Adam
Hi,

look at
 http://www.halyava.ru/document/ind_prog.htm
to get some information about VxD

 Hi all

 to add my 2 cents worth ...
 To access ports under windows 95 or 98 can be done with
 simple assembler no need for a driver  

 {------------------------------------------------------------------------------}
Function WritePort( Address : Word; Value : Byte ):Boolean;Assembler;
{------------------------------------------------------------------------------}
begin
asm
mov dx, Address
mov al, Value
out dx, al
end;
WritePort:=True;
end;
{------------------------------------------------------------------------------}
 function ReadPort( wPort : Word ) : Byte;Assembler;
{------------------------------------------------------------------------------}
asm
   mov dx, wPort
   in al, dx
   mov result, al
end;

Ps the assembler will work for normal IO ports
   If you want to access MEM IO ports
   it can be done even simpler using
   the ABSOLUTE command / option
   ie PORTS : Array [0..10] of byte ABSOLUTE $C9840;
   
Hi marchant,

As I said before, handling the interrupts is a key problem for me. However, your answer is an interesting point of view. I would have two questions regarded to it:
1. Are you sure that it won't generate protection fault under Windows? Because normally it should, but maybe the Windows 95 is too stupid to do so.
2. I read that the non-kernel level I/O access is slower then the kernel-level VxD I/O access. Is it true? Taking in account that your assembler code acesses the ports directly, it seems that it isn't, but who knows...

Thank you for the comment,
Adam
Hi Adam

Well to answer your two questions

I am currently using both tecniques in 98 with
out protection faults. but this depends on if there is
another driver using the same address.

As for the speed ... it could well be slower
the fastest Interface I have used this with is 50hrtz
with a packet size of 80 bytes.

so speed was not really an issue.

( I have used it mainly on old systems where reworking
  the hardware is not an option, but software upgrade
  was nessecary )

I just thought I would mention it to you as the cards
I used this with where originaly Interuppt driven
I just re-worked the "Driver" to polling.

Regards Stephen  
Hello

  I found some components about the ports, I think may they help you

http://www.delphi32.com/vcl/2278
http://www.delphi32.com/vcl/lists/sc_n_23.asp

Mohammed
Hi Marchant and mnasman!

mnasman:
As you will see below, the port access is much simpler than I/we have thought, at least under Windows 95/98: a small and simple asm code. In addition, I have some speed problems, so Marchant's idea seems to be the right solution.
However, I'm interested in some IRQ handling components/ideas, other than using VxDs.

Marchant:
I've tried your code and it works fine. My problem is that I have to transfer a relatively large amount of data. The main loop looks like:

asm
        mov ecx,Count
        mov dx,Port
        mov ebx,BufferPointer;
  @l1:  mov ax,[ebx]
        out dx,ax
        add ebx,2
        dec ecx
        jnz @l1
end;

Count is $20000 = 128KB, and the transfer lasts 0,07 sec (quite slow, I think, and I would be happy if it would be 5-10 times faster). However, without the out command, it is about 50 times faster. So the problem comes obviously from the out commmand (normally the out command shouldn't take more time than a mov command, but it takes 50 times more).

I see two possible reasons:

1. Processing the out command, the processor waits for the ISA clock. (But how does it know that my board is ISA and not PCI? Or, port access uses the ISA clock on PCI bus also?)

2. The out command generates an exception which is handled by the Windows, though without generating any error messages, and that's why it is so slow.

The question is crucial for me, because if 1) is true, then I don't need driver (or maybe only for NT); however, if 2) is true, then I need one, because I would need better speed.
Note that I've read somewhere that the non-kernel I/O access is slower than the VxD I/O access.

My other question: what about NT? I guess it won't let me to access the ports directly. But who knows, I thought that the Windows won't let me either, and I was wrong.

Best regards,
Adam
It is a very bad idea to using direct port access in win32 apps. It is good on a first stage, to check how hardware work. In your case,  you have very big stream of data.
The best solution is to use DMA transfer. Or map you hardware buffer to memory iospace.

PS.
for better perfomance you port address must be word aligned when use out dx,ax.
Hello realzal,  

Welcome to Experts-exchange.  Please read the tips for comments and answer and vist the help desk where you wil find he FAQ and helpful informationa about how the site works.

It may be that your suggest solves the quesioners problem, but the correct way to submit it is as a comment.  This is how the other experts in this thread have been dealing with it in a collaboration.  

The site is large and can be confusing at first, it it best to observe how the more experienced experts condict themselves and follow that lead.  

The other experts are always happy to help you with any problem you have understanding the site.  

I'll be converting your answer back to a comment by rejecting.  Please do not be offended by this the questioner can still accept any comment as answer.

teacher_mod
Community Support Moderator
Experts-Exchange
teacher_mod@experts-exchange.com
Hi realzal,

thanks for the comments, but I guess that reading carefully my initial question and eventually the further comments you can realise that your proposed answer is very far from what I expect.

My question was about writing device drivers using Delphi. Your answer didn't show me whether or how I can do it.

There were suggestions that I don't need to use device driver under Windows 95 for my needs (I guess this isn't true for NT or Windows 2000), and this idea seems to help me (the code above works well), however the problem of the interrupt handling is still unsolved.
Your proposed answer seems to ignore this fact too.

So I have to reject your question.
But -- thanks again for the comment.

Best regards,
Adam
ASKER CERTIFIED SOLUTION
Avatar of ivi
ivi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi ivi :-)

  So you wrote TVicHW32 huh?  It's really a great piece of code! I wish I was smart enough to write something as complicated and geeky as that :-)
Hi Victor!

First of all, I'm very pleased to meet you, and congratulations for your TVicHW32 (I'm still using it for interrupt handling).

I would have a few comments and questions:

1. Unfortunately I can't use TVicHW32 due to the large amount of information which has to be transferred using I/O operations. (Using the port operations of your VxD it was very slow, I need a loop with direct port access [see the asm example above].)

2. I'm afraid you didn't understand the point of my problem with the asm example. The problem is that the OUT command itself makes it slow. Replacing it with a MOV command the speed increases 50-100(!) times. So the OUT command obviously waits for something (maybe the ISA clock or some handshaking mechanism -- I'm not a hardware expert). I would like to understand what's happening.

3. It's not clear for me from your answer whether I can solve my problem with my Delphi 4/5 or not (the link above about the Delphi and VxD said that it works only with Delphi 2 and 3). My pascal code is too big and too well made to translate it to C.

4. Another two problems: it will be a device driver for the market, so it must run on every Windows platfrom (including NT and Windows 2000); on the other hand, it should be a 'normal' windows device, appearing in the Device Manager list. Nobody said a word about how to do that.

Best regards,
Adam

ps. Try to answer as soon as possible if you can. We are nearly from the same part of the world, I guess we will be able to discuss it today.
> 2. I'm afraid you didn't understand the point of my
> problem with the asm example. The problem is that
> the OUT command itself makes it slow. Replacing it with
> a MOV command the speed increases 50-100(!) times.

The MOV command can replace the OUT (or OUTSB) command only if you have your device re-designed to the memory-mapped mechanism. It is the good solution to use memory-mapped i/o instead of port i/o because it is faster in general. But I am not sure if we are talking about the same, not? Just don't see any other situation when OUT command can be changed by MOV command. If you want just compare the speeds then this comparasion can't be correct.

>So the OUT command obviously waits for something (maybe
>the ISA clock

Yes, exactly. The ISA bus inserts the delay cycles to any i/o operation as well as your device can add these delay cycles :) Moreover, the memory-mapped device can add the same delay cycles. It depends how fast is the device.

> 3. It's not clear for me from your answer whether I can
>solve my problem with my Delphi 4/5 or not (the
>link above about the Delphi and VxD said that it works
>only with Delphi 2 and 3).

No one word in your question about your Delphi version...
But it is not important because you wrote:

>4. Another two problems: it will be a device driver for
>the market, so it must run on every Windows
>platfrom (including NT and Windows 2000); on the other
>hand, it should be a 'normal' windows device,
>appearing in the Device Manager list. Nobody said a word
>about how to do that.

Back to your question: "I want to write a very simple device driver for Windows 95, and I'm not sure whether I can do it using Delphi".
Regarding your (4) the answer is very short:
You *must* write your own device driver. It can *not* be done in Delphi at all. The driver's models for Win95 (VxD) and NT-kernel-mode driver or WDM is quite different.
So you *must* have the Windows DDK, *must* have the MSV C/C++ compiler, *must* learn C/C++ programming language, *must* learn the driver's structure, installation issues, driver-to-application communication scheme, registry settings,  etc.
It is impossible to find a simple and non-expensive solution in your case, sorry. Just forget about it. Be ready to the hard, long, and expensive work.
Hi Victor!

>> The problem is that
>> the OUT command itself makes it slow. Replacing it with
>> a MOV command the speed increases 50-100(!) times.

> The MOV command can replace the OUT (or OUTSB) command
> only if you have your device re-designed to the
> memory-mapped mechanism.

I'm sorry I wasn't clear enough. I've replaced the OUT command with a MOV command for speed testing purposes (normally the two operations should have the same duration), and this is what I was talking about. The board I'm writing the driver for is an old and big ISA board, designed for 386, and it definetely doesn't have memory mapped interface, only 16 byte of I/O port space.

But even if my question seems to be not enough clear, fortunately you've answered it:

>The ISA bus inserts the delay cycles to any i/o operation
>as well as your device can add these delay cycles :)
>Moreover, the memory-mapped device can add the same
>delay cycles.

This is the phrase I expected. Thank you.

>So you *must* have the Windows DDK, *must* have the
>MSV C/C++ compiler, *must* learn C/C++ programming
>language, *must* learn the driver's structure,
>installation issues, driver-to-application communication
>scheme, registry settings,  etc.

The only problem which really bothers me from the 'must' list above is the MSV C++. Note that I do have the DDK and I would be able to use it, but my code is alreay in Pascal.
I'm sure the DDK was designed for MSV C++, but as you can see there MIGHT be tricky ways to avoid it (as the VxD with Delphi 2/3 link shows).
That's why I'm a bit sceptic regarding to these explicit statements.

Best regards,
Adam
mmmmm ok ....
>That's why I'm a bit sceptic regarding to these explicit statements.

Trust me :) You can write NT-style or a WDM devicve driver *only* in MSVC. The VxD can be written in C++Builder also, but NT/WDM driver in MCVC only.
Even you will able to write your driver in Pascal (just for a curious) you can't link this driver without the MS linker. Also it is very difficult to translate all *.h files from MS DDK to Pascal.
Believe me Adam ivi is right !

No way on earth to write a driver with out it.
Your original question was for 95 there you can still get away with using delphi

Regards Stephen
Adam

I have never heard of an ISA device that could ever run at the speeds you want, as the ISA Buss itself could not handle that kind of trafic ... are you 100% sure that is your problem ?

Stephen  
Hi Stephen!

I don't know what's happening, maybe my English is too bad, but I've explained my problem regarding to the uploading asm example a few times and it seems nobody understands it.

I try to explain it again.

The card I use is a 10 years old ISA board (I want to write a Windows driver for it). I knew from the start that its speed is limited by its age, but I didn't know how the PC manages these speed limitations.

First, I used Victor's VxD, and the speed was very bad (which is fully understandable, because in the main loop there were at least 3 function calls instead of a simple OUT command).
Then I tried your suggestion, and the speed increased to a limit (about 1,5 MB/sec through a 16-bit port), and it wasn't influenced by the speed of the PC anymore.
It was clear for me that the limitation comes from the hardware and not from the processor (as I explained before, I've tried replacing the OUT command with a MOV command, and of course the execution time of the loop decreased 50-100 times; in the same time, putting two OUT commands instead of one, the execution time increased almost exactly 2 times).

So it was very clear for me that the OUT command is the 'faulty' one. But I didn't know (and it isn't entirely clear fo me even now) how exactly the OUT command waits for the hardware.

My initial idea was that it waits for the ISA clock; but I didn't understand what happens with the non-ISA (PCI, AGP etc.) devices?

Then Victor suggested that the extension board can insert delay cycles. This seems very logical to me (it looks like a kind of handshaking mechanism), but I don't really understand how it works.

So, once again: my problem is that I don't fully understand what's happening exactly around the OUT command. The speed of the uploading isn't a problem for me anymore, I understand that it's slow because its speed is limited by the hardware, and I understand that -- from the processor side -- it comes from the OUT command, which waits for the hardware.

All the best,
Adam