www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/08/02/07:20:34

Date: Wed, 2 Aug 1995 13:54:29 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Steve Havelka <shavelk AT agora DOT rdrop DOT com>
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: Video Question Part II

On Tue, 1 Aug 1995, Steve Havelka wrote:

> Ok, someone directed me to sys/farptr.h as the solution
> to the 0xd0000000-under-DPMI problem.  I decided to
> give it a shot, but it fails too.  It GPFs on the
> access to 0xa0000 and 0xb8000.  I'd really like to be
> able to directly manipulate the text screen in DJGPP,
> but I can't directly do it, nor is it mapped anywhere.
> Also, I checked the FAQ already and it didn't contain
> any such information.  Thanks!

But it _is_ in the FAQ:

18.4  Q: How can I move data between my program and the transfer buffer?
      Q: How do I access my peripheral card which is memory-mapped to an
         address between 640K and 1M?
      Q: How can I read or change a value of one of the variables in the
         BIOS data area?
      Q: How can I peek at an address whose far pointer I get from an INT
         21h call?
      A: 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 on
             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.

             Note that some memory-mapped peripheral devices might require
             16-bit word accesses to work properly, so if dosmemXXX()
             yields garbled results, use farptr functions or movedata()
             (see below).

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

18.5  Q: I call movedata() to pass data between my program and the
         transfer buffer, but get bogus values or General Protection
         Fault.
      A: Valid conventional-memory addresses are only 20 bit-wide.
         However, the value held stored in the variable
         _go32_info_block.linear_address_of_transfer_buffer is not
         guaranteed to have the higher 12 bits zeroed, and movedata()
         doesn't mask those high bits, because it can also be used to move
         data between 2 protected-memory locations.  Be sure to mask off
         the high 12 bits of the value returned by various
         ...._linear_address_... fields in go32 structures, before you
         call *any* of the above functions.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019