delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1999/12/02/21:38:07

From: "Chaos" <chengin AT alpha DOT net DOT pl>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: nearptr access to memory mapped devices
Date: Sun, 28 Nov 1999 23:14:44 +0100
Organization: Chaos Engine
Lines: 87
Message-ID: <826blb$1m7$1@portraits.wsisiz.edu.pl>
References: <81s582$bmt$1 AT nntp8 DOT atl DOT mindspring DOT net>
NNTP-Posting-Host: pf39.warszawa.ppp.tpnet.pl
X-Trace: portraits.wsisiz.edu.pl 944157163 1735 212.160.57.39 (2 Dec 1999 17:52:43 GMT)
X-Complaints-To: abuse AT news DOT wsisiz DOT edu DOT pl
NNTP-Posting-Date: 2 Dec 1999 17:52:43 GMT
X-Newsreader: Microsoft Outlook Express 4.72.3110.1
X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.1
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

>/*spec starts*/
>1. Map the physical memory address to a linear memory address (using DPMI
>function 0x800 for example).
>
>2. Find the base address for the default DS selector for your operating
>environment.
>
>3. Subtract the base address from the linear address computed in step 1 to
>give you a near pointer (relative to DS) that you can use from within your
>code.
>/* spec ends */
>
>Okay sounds good. I interpret it this way for doing it in djgpp assuming
>I've already determined the address and size of the lfb:
>
>/* code starts */
>void *lfbptr;
>__dpmi_meminfo meminf;
>unsigned long baseaddr;
>
>/* step 1 */
>meminf.address = address_of_lfb;
>meminf.size = size_of_lfb;
>__dpmi_physical_address_mapping(&meminf);
>
>/*step 2 */
>__dpmi_get_segment_base_address(_my_ds(), &baseaddr);
>
>/* step 3 */
>lfbptr = meminf.address - baseaddr;
>/* code ends */
>
>The problem is that when I go to use lfbptr, I get SIGSEGV. Actually I'm
not
>trying to use a lfb but I'm trying to access a memory mapped device above
>the 1mb mark and I thought this could be used for that as well. So my
>question is, am I doing this right, or does the method suggested by the vbe
>spec not work? If the method suggested doesn't work why is it in the vbe
>spec???

Well, I think you get SIGSEGV coz the calculated address is wrong.
I'm not going to go deeper into that code, coz I not too good at this
either, but take a look at how I did that.

 __dpmi_meminfo mem;

// Here is the stuff from VBE structure.
mem.size = (unsigned long)(VESA_Mode_Info.XResolution *
VESA_Mode_Info.YResolution);
mem.address = VESA_Mode_Info.PhysBasePtr;

if(__dpmi_physical_address_mapping(&mem))
     {
      fprintf(stderr,"Can't map LFB!\n");
      return 1;
     }
if( (VideoSelector = __dpmi_allocate_ldt_descriptors(1))==-1)
    {
     fprintf(stderr,"Can't allocate descriptor\n");
     return 1;
    }
if(__dpmi_set_segment_base_address(VideoSelector, mem.address)==-1)
    {
     fprintf(stderr,"Can't set base address of selector\n");
     return 1;
    }
if( (__dpmi_set_segment_limit( VideoSelector,your_memory_allocated_for_LFB))
==-1 )
    {
     fprintf(stderr,"Can't set limit of descriptor!\n");
     return 1;
    }
It runs OK on my machine. But remember to align your segment limit to 4KB
(thanks Eli) if you want to use more than 1MB limit. Here's what FAQ says:

"Note that the segment limit should be one less than the size. Also,
segments over 1MB in length must be a multiple of 4KB, otherwise the DPMI
server might fail the call, or silently change the limit. "

I hope I helped a just a little.

Take care.
-=| Chaos |=-
e-mail:  chengin AT alpha DOT net DOT pl
              chengin AT polbox DOT com


- Raw text -


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