delorie.com/djgpp/faq/lowlevel/memtrans.html
|
search
|
How can I move data between my program and the transfer buffer?
How do I access my peripheral card which is memory-mapped to an
address between 640K and 1M?
How can I read or change a value of one of the variables in the
BIOS data area?
How can I peek at an address whose far pointer I get from an INT
21h call?
Depending on your specific needs, you can use one of three methods:
- If you want to access a byte, a 16-bit word, or a 32-bit double
word, use the far pointer functions documented in the
sys/farptr.h header file. You should convert any real-mode
far pointer segment:offset pair into a linear address (segment*16 +
offset), and use _go32_conventional_mem_selector() to get the
selector which allows access to conventional memory, like this:
u_char value = _farpeekb(_go32_conventional_mem_selector(),
segment*16 + offset);
Use _farpeekw() to peek at 16-bit shorts and
_farpeekl() to peek at 32-bit longs. If you need to access
several (non-contiguous) values in a loop, use corresponding
_farnspeekX() functions which allow you to set the selector
only once, as opposed to passing it with every call.
There is a corresponding set of _farpokeX() and
_farnspokeX() functions to poke (change the values of) such
memory locations.
These functions have an advantage of emitting inline assembly code
when you compile with optimizations, so they are very fast.
- If you need to access more than 4 contiguous bytes, use
dosmemget() and dosmemput() library functions
(documented in libcref.i file). They also require that you
convert the segment:offset pair into a linear address, but they don't
need the conventional memory selector.
- For moving buffers larger than a few tens of bytes, it's best to
use movedata() library function (also documented in
libcref.i file). It requires that you pass selector and
offset for both the conventional memory address and for the buffer in
your program's address space. Use the function _go32_my_ds()
to get the selector of any variable in your program, and its address
as its ``offset'' or linear address. movedata() is faster
because it moves by 32-bit longs, but be careful with its use when
moving data to and from peripheral cards: many of them only support 8-
or 16-bit wide data path, so moving data 4 bytes at a time won't gain
you much, and might even get you in trouble with some buggy
BIOSes.