Solved

Writing device driver in Delphi

Posted on 2001-07-21
29
646 Views
Last Modified: 2010-04-06
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?
0
Comment
Question by:biroadam
  • 7
  • 6
  • 3
  • +6
29 Comments
 
LVL 22

Expert Comment

by:mnasman
Comment Utility
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
0
 

Expert Comment

by:teacher_mod
Comment Utility
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
0
 
LVL 3

Expert Comment

by:lopem
Comment Utility
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)
0
 
LVL 5

Expert Comment

by:Gwena
Comment Utility
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 :-)
0
 
LVL 22

Expert Comment

by:mnasman
Comment Utility
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
0
 

Author Comment

by:biroadam
Comment Utility
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
0
 
LVL 2

Expert Comment

by:bugroger
Comment Utility
Hi,

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

Expert Comment

by:marchant
Comment Utility

 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;
0
 
LVL 1

Expert Comment

by:marchant
Comment Utility

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;
   
0
 

Author Comment

by:biroadam
Comment Utility
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
0
 
LVL 1

Expert Comment

by:marchant
Comment Utility
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  
0
 
LVL 22

Expert Comment

by:mnasman
Comment Utility
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
0
 

Author Comment

by:biroadam
Comment Utility
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
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Expert Comment

by:realzal
Comment Utility
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.
0
 

Expert Comment

by:teacher_mod
Comment Utility
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
0
 

Author Comment

by:biroadam
Comment Utility
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
0
 
LVL 2

Accepted Solution

by:
ivi earned 200 total points
Comment Utility
First, let me introduce the Karen Hazzah's book called "Writing Windows VxDs and Device Drivers".
*And* is the key word. You can write your Windows 95/98/ME driver as a DLL or as a VxD (not applicable for NT/200/XP!). Possible solutions:

1. You can write 16-bit DLL using Delphi 1. In this DLL you can install an interrupt handler as well as get full port i/o access. You can use a "thunk" mechanism to access this DLL from an application written with Delphi 2+ (32-bit).

2. You can even write a VxD using 32-bit Delphi (see link above). But it is not a trivial task, you must have the basic VxD knowledge.

3. Thank you for your interest in my TVicHW32 :)

About your ASM example - you can make it much faster:

asm
  cld
  mov dx,Port
  mov ecx,Count
  mov esi,BufferPointer
  rep outsb
end;

But I'd recommend you read this link before:

http://www.entechtaiwan.com/TVicHW32faq.htm#Win9xDirect

Good luck,
Victor
0
 
LVL 5

Expert Comment

by:Gwena
Comment Utility
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 :-)
0
 

Author Comment

by:biroadam
Comment Utility
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.
0
 
LVL 2

Expert Comment

by:ivi
Comment Utility
> 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.
0
 

Author Comment

by:biroadam
Comment Utility
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
0
 
LVL 1

Expert Comment

by:marchant
Comment Utility
mmmmm ok ....
0
 
LVL 2

Expert Comment

by:ivi
Comment Utility
>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.
0
 
LVL 1

Expert Comment

by:marchant
Comment Utility
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
0
 
LVL 1

Expert Comment

by:marchant
Comment Utility
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  
0
 

Author Comment

by:biroadam
Comment Utility
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
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now