www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/01/06/06:00:35

Sender: robertjs AT bbcgate DOT bbc DOT co DOT uk
Message-ID: <34B20E67.2F1CF0FB@rd.bbc.co.uk>
Date: Tue, 06 Jan 1998 10:58:47 +0000
From: Robert Smith <Robert DOT Smith AT rd DOT bbc DOT co DOT uk>
Organization: BBC R&D Department
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
CC: djgpp AT delorie DOT com
Subject: Accessing Phyical Memory Above 1 MB - Clarification

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