www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/08/21/05:33:51

Date: Mon, 21 Aug 1995 11:30:06 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Tapio Vocadlo <taps AT cyberstore DOT ca>
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: GPF when accessing video memory directly

On Sun, 20 Aug 1995, Tapio Vocadlo wrote:

> Using the _farpokeb and related functions in sys/farptr.h
> compiles fine, but then GPFs with a 'unsupported int 0x0D'
> message when run. All I'm doing is
> 
> #include <sys/farptr.h>
> 
> unsigned char gc=65;
> 
> _farpokeb(0xb800,0,gc);

What you should do is this:

  _farpokeb(_go32_conventional_mem_selector(), 0xb8000, gc);

(the 3 `0's in B8000h is NOT a typo, see below).

This is explained in the DJGPP FAQ list (available as faq102.zip from the 
same place you get DJGPP):

10.6  Q: I try to access the video memory at 0xa0000, but get Segmentation
         violation...
      A: Absolute addresses of certain memory-mapped devices are mapped
         differently under DJGPP, which is protected-mode environment.
         You can't just poke any address, that's what protected mode is
         all about.  In non-DPMI mode, the entire graphics video memory is
         mapped 1:1 starting at 0xD0000000 in the program's address space;
         the DJGPP paging mechanism  understands how SuperVGA's map their
         memory onto the AT bus and automatically swaps pages as the
         program tries to access them.  The program sees a linear range
         from 0xD0000000 to 0xD0100000 that corresponds to each pixel in
         the 256-color modes of SuperVGAs.  For this to work correctly,
         you will have to set the GO32 environment variable to the
         graphics driver suitable for your SuperVGA card, like this:

          SET GO32=driver c:\djgpp\drivers\ati.grd gw 640 gh 480 tw 132 th 43

         In DPMI mode this won't work.  As DJGPP v2.0 will be DPMI-only
         environment, this means that, after GRX 2.0 arrives, the above
         method should be used only as last resort.  If you want to write
         a program which will compile and run unchanged in v2.0, use
         functions described in <sys/farptr.h> (see chapter 18 below for
         details).

And then section 18.4 says:

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.

- Raw text -


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