From: "Chaos" 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