www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/02/05/10:33:07

Date: Thu, 5 Feb 1998 10:31:48 -0500 (EST)
From: "David J. Coffin" <dcoffin AT shore DOT net>
To: Robert DOT Smith AT rd DOT bbc DOT co DOT uk
cc: djgpp AT delorie DOT com
Subject: Re: Accessing Phyical Memory Above 1 MB - Clarification
Message-ID: <Pine.GSO.3.96.980205102650.16863A-100000@shell2.shore.net>
MIME-Version: 1.0

Robert Smith,

> __dpmi_set_segment_limit(Sel,MemInfo.address + BOARD_MEMORY_SIZE - 1l);

The segment limit is relative; it does not include the address.

     In the second case, you must call __djgpp_nearptr_enable(),
allowing DS to access all linear memory.

     I tried both methods, pasting your code and making sure
that all DPMI calls were passed the right arguments and returned
without error.  But any attempt to read or write physical memory
causes a page fault.

     The crash dump shows FS, FS-base, FS-limit, and the index
register (EAX, EDX, or ESI) to have the correct values.

     I also tried CWSDPR0, which doesn't support virtual memory.
It still gives page faults.  BTW, I'm using MS-DOS 5.0.

     Did you get your code to work yet?

					Dave Coffin  2/5/98
Robert Smith wrote:

> I am about to port some code which controls a proprietary
> memory mapped (above 1 MB) PCI board to DOS using DJGPP.
> Based on the current design of the code, I would like to access
> to card's memory mapped area through a pointer to a structure.
> Specifically I would like to:
> 
> 1) Initialise this pointer once in the application software
>    (when opening the interface)
> 2) Deference the pointer at various points during
>    the life of the application before the interface
>    is closed.
> 
> Based on the DJGPP FAQ (section 18.7 - Accessing memory above 1MB)
> and a response to a recent comp.os.msdos.djgpp newsgroup posting (
> Re:dos_ds - Response from DJ Delorie, Sun 4 Jan 1998), I am not sure
> that it is possible to do what I wish using DJGPP.  However, this may
> be due to ignorance on my part.  Hence I will state my understanding
> of what can be done and invite fruitful comments.
> 
> 
> My Understanding of How to Access Physical Memory Above 1 MB with DJGPP
> ==========================================================
> 
> >From section 18.7 of the DJGPP FAQ, I understand that I have to do
> something like the following to initialise a pointer (base address of
> PCI board memory assumed to be 0x1000000, size of memory assumed to
> be 16 Kbytes, error handling not included here for clarity) :
> 
> /****************************************************************/
> 
> #include <dpmi.h>
> 
> /* Board base address and memory size  */
> #define BOARD_BASE_ADDRESS 0x1000000l
> #define BOARD_MEMORY_SIZE  (16l*1024l)
> 
> /* Variables */
> short          Sel;
> __dpmi_meminfo MemInfo;
> unsigned char  Data8;
> unsigned long  Data32;
> 
> /* Allocate LDT descriptor */
> Sel = __dpmi_allocate_ldt_descriptor(1);
> 
> /* Map selector to phyical address ? */
> MemInfo.address = BOARD_BASE_ADDRESS;
> MemInfo.size    = BOARD_MEMORY_SIZE;
> MemInfo.handle  = 0l;
> __dpmi_phyical_address_mapping(&MemInfo);
> 
> /* Lock the linear address */
> __dpmi_lock_linear_region(&MemInfo);
> 
> /* Set segment base address */
> __dpmi_set_segment_base_address(Sel,MemInfo.address);
> 
> /* Set segment limit */
> __dpmi_set_segment_limit(Sel,MemInfo.address + BOARD_MEMORY_SIZE - 1l);
> 
> /****************************************************************/
> 
> Then to access the boards memory I must do something like the following:
> 
> /****************************************************************/
> 
> /* Reading a byte from the start of the boards memory */
> Data8 = _farpeekb(Sel,0l);
> 
> /* Inverting the second double word in the boards memory */
> Data32 = _farpeekl(Sel,4l);
> Data32 = ~Data32;
> farpokel(Sel,4l,Data32);
> 
> /****************************************************************/
> 
> 
> The above does not provide what I want since it is necessary to
> use the routines in <sys/farptr.h> to access the memory, whereas
> I wish to access the memory directly.
> 
> 
> >From the DJ Delorie's response to comp.os.msdos.djgpp newsgroup posting
> Re:dos_ds, (Sun 4 Jan 1998), I believe that it is also possible for
> me to access the boards memory as follows:
> 
> /****************************************************************/
> 
> /* Board base address   */
> #define BOARD_BASE_ADDRESS 0x1000000l
> 
> /* Structure defining the boards memory layout */
> struct BoardMem_s
>   {
>   unsigned char Reg0;
>   unsigned char Reg1;
>   unsigned char Reg2;
>   unsigned char Reg3;
>   unsigned long Reg4;
>           :
>   };
> /* Variables */
> struct BoardMem_s* BoardMem;
> unsigned char      Data8;
> 
> /* Initialise board memory pointer */
> BoardMem = (struct BoardMem_s *) BOARD_BASE_ADDRESS -
> __djgpp_base_address;
> 
> /* Reading a byte from the start of the boards memory */
> Data8 = BoardMem->Reg0;
> 
> /* Inverting the second double word in the boards memory */
> BoardMem->Reg4 = ~BoardMem->Reg4;
> 
> /****************************************************************/
> 
> The above is closer to what I want, but I will have to
> re-initialise the board memory pointer (BoardMem in the
> example above) each time I enter a segment of code which
> accesses the board (assuming that it cannot be guaranteed that
> __djgpp_base_address has not changed).
> 
> --------------------------------------------
> Any opinions expressed here are my own and
> not necessarily those of the BBC.
> **************************************************
> *   Robert Smith
> *   BBC Research & Development Department.
> *   Kingswood Warren, Tadworth, Surrey. KT20 6NP
> *   Phone:      +44 1737 836615 (direct)
> *   Fax:        +44 1737 836665
> *   Email:      Robert DOT Smith AT rd DOT bbc DOT co DOT uk
> **************************************************

- Raw text -


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