Posted on 1997-06-19
Last Modified: 2010-04-04
This is also a big problem of mine. I was able to read from memory and these kind of things in BPascal but in D3 there is no procedure like MEM or no variable like SEG0040? Please, help me. I need to read and write to a certain part in memory. Don't let me down. Greets  Jakub.
Question by:jakubklos
  • 6
  • 5
  • 3
  • +1

Expert Comment

ID: 1337256

In 32-bits windows each program (=process) runs in a virtual memory space. 0040:xxxx translated to a 32-bit address would not point to physical 0040:xxxx, and not contain what you're looking for.

If you tell what information you need, I'll try pointing out alternative methods to get them.




Author Comment

ID: 1337257
I need to read and write from a PCCOM Card and that is reading and writing from an absolute address in memory (DOS 0 Base)

Author Comment

ID: 1337258
Because I have to reach to DOS based memory (reading and writing to a PCCOM cards). Please, help.
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.


Expert Comment

ID: 1337259
This ain't a Delphi question... You need to write a VxD (for Win95) or a kernel-mode driver (Win NT), and for this you should have MS VC++ and MS DDK for 95 and/or NT.

But, there does exist a freeware/shareware component and driver which I believe will allow you to read/write absolute memory. Look up for information.




Author Comment

ID: 1337260
Thanks Erik, I'll have a look at it.

Expert Comment

ID: 1337261
I have here this piece of hardware who uses a custom made 16 bit card. I had to read/write some value's from/to this card. What I did is I'll wrote a small piece of assembler within Delphi. Can I help you with this piece of code??? If so let me know!!

Author Comment

ID: 1337262
I could say I'm a good assembler programmer but I'm not sure it will work. Are you sure W95 will not complain that I want to write to memory or something. Did you just do that or did you try to bluff W95 somehow that they didn't know what you were doing?

Accepted Solution

millerw earned 100 total points
ID: 1337263
This is not really an answer but I do have a question for you:

Have you ever looked up ABSOLUTE keyword in Delphi?

Here is the Borland Help File information on it:

absolute address


The standard directive absolute declares a variable that resides at a specific memory address.
You can do either of the following:

Assign the variable directly to a specific address
      Declare the variable to reside at the same memory address as another variable

The first form directly specifies the address of the variable.
The second form declares a new variable on top of an existing variable (at the same address).
The variable declaration's identifier list can specify only one identifier when an absolute clause is present.

Look in the help file under Absolute for examples and such.  I have some programs of my own to show but they are not in delphi.  They are in Turbo Pascal 7.0

Good Luck,

Expert Comment

ID: 1337264
The second form of absolute is valid and working in 32-bits windows. The first form is not usable, simply because each process live in its own address space, and attempts to access memory outside of this memory area will cause an Access Violation.

Accessing absolute memory under Win95/NT requires code running in kernel mode, and to get code to run in kernel mode you need a driver.




Expert Comment

ID: 1337265
Sperling---Do you think any of this will work?
Port command and win95, a

From: Martin Larsson <>


This was supposed to be a quick summary. It ended up being quite long. Hope it's not
too boring...


Under MS-DOS, an application has control of the entire machine. This gives the
programmer a lot of freedom. To maximize speed, you can access the hardware
directly if necessary.

Under Windows 3.x, this freedom was somewhat limited. You were no longer
allowed to write directly to the screen, among other things. The problem is obvious:
since the user could have any number of applications running, there was no guarantee
that they were not accessing the same hardware simultaneously.

Another problem that showed up was that you had to be nice to the other applications
running at the same time. Win 3.x is co-operatively multitasked, meaning that each
application determines when it's done and other applications can run. Hogging the
CPU for longer periods of time was not considered nice.

But the fact that no applications would run unless we as programmers said so, could
be worked to our advantage when accessing the hardware. Since the application were
guaranteed full control over the machine for as long as it wished, it could, when it got
the CPU, muck with the I/O ports or memory, but not give up control until it was

Unfortunately, progress caught up with us; now there's Win32 (Windows NT and
Windows 95). T hese are true operating systems, with true pre-emptive multi-tasking.
Each thread (the execution unit) gets a certain amount of time with the processor.
When the time is up, or a thread with higher priority comes along, the system will
switch to the next thread, even though the first thread is not done. This switching can
occur between any two assembly instructions; there's no guarantee that a thread will
be able to complete any number of instructions before it's pre-empted, and there
might be a long time 'till the next timeslot.

This brings up a real problem with direct hardware access. A typical I/O read, for
instance, is composed of several assembly instructions:

        mov dx, AddressPort
        mov al, Address
        out dx, al
        jmp Wait
        mov dx, DataPort
        in  al, dx

While the state of all registers are preserved on a thread-switch, the state of the I/O
ports are not. So, it is very possible that three applications have their way with 'your'
I/O port between the 'out' and the 'in' instructions above.


The solution to this problem is to somehow tell all other applications that "Currently
MyProg is using port 546, and everybody else better stay in line." What's needed is a
mutex. Unfortunately, to use a mutex, all applications have to agree on a name for that
mutex. But even if that was possible, you'd easily get into some thorny problems.
Consider two applications App1 and App2. Both wants to execute the above code.
Unfortunately, they're created by different people with different views, so App1 asks
for the AddressPortMutex first, while App2 asks for the DataPortMutex first. And,
by a sad coincidence, App1 gets the AddressPortMutex, then the system swithes to
App2, which aquires the DataPortMutex, and we're deadlocked. App2 can't get the
address port, 'cause App1 has that. App1 can't get the data port, 'cause App2 has
that. And we're still waiting...

The correct way to solve this problem is to create a device driver that owns the
port/memory area. Access to the hardware is supported through an API. A typical
function would be

GetIOPortData(AddressPort, DataPort : word) : Byte;

GetIOPortData would aquire a mutex that protects both (possibly all) ports, then
access the ports, and finally releasing the mutex before returning to the caller. If
different threads are calling this function at the same time, one will get there first, the
others must wait.

Writing a device driver is not easy. It must be done in assembler or C, and they are
really hard to debug. And just to be safe, a device driver for Windows 95 (a VxD)
isn't compatible with a device driver for Windows NT (a VDD, for virtual device
driver). They are said to converge, and Windows NT 6.0 and Windows 2000 might
have compatible device drivers, but until then, we're stuck with writing two separate
pieces of code.

For more info see (for instance):

     Microsoft's Windows 95 Device Driver Kit

     Microsoft's Windows NT Device Driver Kit

     Microsoft Press' "Systems Programming for Windows 95" by Walter Oney

Also, check out Vireo's VtoolsD library for writing VxD's in C.


The above problem isn't too real. An application that accesses the hardware directly,
is usually using some specialized hardware. A machine-configuration like that tend to
run one application only, who's sole purpose is to access that hardware. In such a
scenario, writing a device driver seems too much trouble. After all, the reason the
thing is running on Windows, is just to get the nice GUI for (almost) free, not that 10
applications can be running simultaneously.

Fortunately, Windows 95 is built to be compatible with Windows 3.x. This means that
direct I/O must be allowed, simply because a lot of Win 3.x programs uses it. To
access the I/O ports, simply step down to assembly. The following code was supplied
by Arthur Hoornweg (

    function getport(p:word):byte; stdcall;
         push edx
         push eax
         mov  dx,p
         in   al,dx
         mov  @result,al
         pop  eax
         pop  edx

    Procedure Setport(p:word;b:byte);Stdcall;
        push edx
        push eax

        mov dx,p
        mov al,b
        out dx,al

        pop  eax
        pop  edx

Frangois Piette also has some direct I/O access functions at


The above will not work on Windows NT. NT is a much more robust operating
system, and allowing all and everybody access to the hardware anytime they wanted,
would seriously endager the stability. In addition, NT is cross platform, and access to
I/O ports might be wildly different on different processors.

Even so, it is possible to access the I/O ports directly under NT on x86 processors.
This is highly undocumented, and will probably disappear in future versions of the
operating system.

I have not much information on the process, but an article by D. Roberts in the May,
1996 issue of Dr. Dobb's Journal looks promising: "Direct Port I/O and Windows
NT." This seems to be the only DDJ I'm missing, so I can't verify it. See for ordring of back-issues.

Windows Developer's Journal does have an article on "Port I/O under Windows." It's
written by Karen Hazzah, and appeared in the June 1996 issue. See for ordering of back-issues.


(Note, I know very little about these resources, check them out yourself.)

There are newsgroups dedicated to the topic of writing VxD's and VDD's: (VDD) (VxD)

Dejanews ( turned up quite a few hits on 'device driver
direct I/O access 95'.

BlueWater Systems have developed OCX's for direct I/O, memory access and
interrupt handling under all Win32 platforms. They also seem to offer custom built
device drivers. See their page at

I know some other company has been advertising here for their ability to write custom
VxD's. But I can't find that reference.
If you want to see this first hand, Goto the Unoffical Delphi Developers FAQ at

Expert Comment

ID: 1337266
I remember that DDJ article, it described a way to modify the protection/rights to access certain hardware for certain processes. Basically, this was used internally in NT to allow graphics drivers to access some of the hardware directly, because graphics drivers were not running in kernel mode. In NT 4, graphics drivers have moved to running in kernel-mode, and as this technique (which BTW was *very* complicated, but then, all DDJ articles are) is not necessarry in NT 4, I doubt Microsoft has left the possibility in.

In Windows 95, you can have some but not full access to hardware. You haven't got any guarantees that noone else will access the same hardware, and no guarantee against thread switches while you're working with it.

AFAIK it should be possible to access hardware as under Win 3.1 if you do this using a 16-bit DLL and thunking. If you wan't to do this in native 32-bit code under win 95, more restrictions apply, and if you move to NT, forget it.

In short: *Reliable* access to an IO port or absolute memory requires a driver. Almost reliable or Unreliable access is possible in Win 95 without a driver, using the assembly you mentioned, or via thunking.




Expert Comment

ID: 1337267
Hmmm.... Rephrasing...

For apps that are to be sold/deployed, use a driver. For apps you're going to use yourself, try without the driver.



Author Comment

ID: 1337268
If I then wanted to help with programming this driver would be there anyone to help me with some information?

Expert Comment

ID: 1337269
What exactly are you trying to do with your card?  I have experience with a PC Lab Card from Advantech.  Drivers are a pain to write.  If you want to check out Advantech their site is

They have a dll written already to interface with all their cards and I already have the C++ Header file sent with the software translated into Delphi with most of the functions tested (some are not tested yet because I haven't had need for them).  If you want to try them I think that may be your best bet.  

I called PCCOM and asked them if they had any dlls to interface with their cards.  Their response was "We don't know what those are."  And to the question of when they might be coming out with some Windows drivers for their cards, they responded, "We have no plans for anything like that."  Companies that are not willing to get into the real world market are not worth your time.  

Advantech fully supports all their cards, the cards are easy to use, and I already have a Card_Face object written to interface to all their cards.  The card I used was the PC812-PG card and it had 2 analog outputs, 16 analog inputs, 16 boolean inputs, and 16 boolean outputs.  We used it to control a dynomometer in college and it worked very well to control all the systems that it needed to.  Additionally, it was fast (my code was the only thing that slowed down data retrival).  We were able to get a reading every 0.25 seconds with over 6000 lines of code running on a 486.  Below that time, the screen could not refresh in time before the next read.

Good Luck,

Author Comment

ID: 1337270
It looks like that it isn't a problem anymore. I have found some site, where are some DLLs that can handle this writing and reading from absulute address and also some port accessing etc. So now you know. And also on the delphi super page there is a freeware PORTHW32 component for D2, that does exaclty the same, I'm using D3 though. I've contacted the author and now we are conversating. So thank you for all.

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…

831 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