Link to home
Start Free TrialLog in
Avatar of jakubklos
jakubklos

asked on

READ AND WRITE TO MEMORY

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.
Avatar of sperling
sperling

Why?

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.


Regards,

Erik.


Avatar of jakubklos

ASKER

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)
Because I have to reach to DOS based memory (reading and writing to a PCCOM cards). Please, help.
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 http://www.entechtaiwan.com/tools.htm for information.


Regards,

Erik.


Thanks Erik, I'll have a look at it.
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!!
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?
ASKER CERTIFIED SOLUTION
Avatar of millerw
millerw

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
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.

Regards,

Erik.


Sperling---Do you think any of this will work?
---Start---
Port command and win95, a
summary.

From: Martin Larsson <martin.larsson@delfi-data.msmail.telemax.no>

APPOLOGY

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

THE PROBLEM

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
done.

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
    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 DOCUMENTED WAY

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.
http://www.vireo.com/.

THE UNDOCUMENTED WAY

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 (hoornweg@hannover.sgh-net.de):



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


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

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

        pop  eax
        pop  edx
      end;
    end;



Frangois Piette also has some direct I/O access functions at
http://rtfm.netline.be/fpiette/portiofr.html

BUT WHAT ABOUT NT?

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
http://www.ddj.com 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
http://www.wdj.com for ordering of back-issues.

RESOURCES

(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:

     comp.os.ms-windows.programmer.nt.kernel-mode (VDD)

     comp.os.ms-windows.programmer.vxd (VxD)

Dejanews (http://www.dejanews.com) 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 http://www.bluewatersystems.com/.

I know some other company has been advertising here for their ability to write custom
VxD's. But I can't find that reference.
---End---
If you want to see this first hand, Goto the Unoffical Delphi Developers FAQ at http://www.sbrain.syh.fi/delphi/devfaq/index.html
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.

Regards,

Erik.


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.

Regards,

Erik.
If I then wanted to help with programming this driver would be there anyone to help me with some information?
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
http://www.advantech.com.tw/

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,
Scott
It looks like that it isn't a problem anymore. I have found some site www.internals.com, 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.
Regards,
Jakub.