delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/01/11/03:26:50

From: "John M. Aldrich" <fighteer AT cs DOT com>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: memory size
Date: Fri, 10 Jan 1997 18:55:19 -0800
Organization: Two pounds of chaos and a pinch of salt
Lines: 142
Message-ID: <32D70117.1C40@cs.com>
References: <5b58t0$ok AT netserver DOT univ-lille1 DOT fr>
Reply-To: fighteer AT cs DOT com
NNTP-Posting-Host: ppp101.cs.com
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

LECROART Vianney wrote:
> 
>                 Hi,
> 
>         I want to know if there are some functions to knows exactly how many
> mega of memory have the computer and how many are free.
>         Thanks for help me.

Well, I just posted an answer to this exact problem last night.  Why is
it that identical questions always seem to come in "waves," even though
the users in question can't possibly have any connection with one
another?  Why is it that they never read the newsgroup to see if anybody
else has answered a similar question?  Oh, well.  :)

Here's my reply snipped from the other post.  Good luck!

BTW, I suggest you look up all the indicated functions in the DJGPP libc
documentation, as well as in the FAQ.  There are a lot of things about
memory management that can't be explained with simple comments in the
source code.  :)

8<----snip-----

This bit of code from my DJVERIFY program comes courtesy of Eli
Zaretskii.  All parts are commented, so you shouldn't have too much
trouble understanding it.  :)

The code reads the CMOS to return the amount of memory installed on
the system in kilobytes.  It is accurate for the most part, but there
are a few things you should know about the methodology used:

 - The CMOS value wraps around at 64 MB.  If the computer has more
   than this installed, the only way to find the correct value is
   to compare the value the CMOS reports to the free physical memory
   reported by _go32_dpmi_remaining_physical_memory().  If the latter
   is greater, then you must add 64 MB to the value obtained.
   I haven't tested this 100%, but it should work.

 - The value reported will not include memory used for ROM shadowing.
   On most computers, this amount is around 300 KB.  In order to
   prevent the user from thinking he has less memory than he really
   does, I round the value up to the nearest megabyte.  You can do
   this or not depending on the level of accuracy you need.

 - It has been suggested that certain OS's, such as Windows/NT, may
   report less memory than is actually installed on the system.  I
   have never had a report of this actually happening, but be aware
   that it could.  In any event, it should always report at least
   16 MB, if the system actually has that much.
   
-snip-

#include <dpmi.h>
#include <time.h>
#include <pc.h>

#define UMAX(a, b)              ((a) > (b) ? (a) : (b))

static void usec_sleep          ( int usec );
static unsigned char read_cmos  ( int reg );
int    installed_memory_size    ( void );

void analyze_system( void )
{
    [ unnecessary parts snipped ]

    /* Detect max/free memory */

    /* Since this value is usually off by 250-500KB due to ROM
shadowing,
     * I round it up to the nearest megabyte, and then convert to bytes.
     */
    system_specs.max_phys_mem = ( ( installed_memory_size( ) - 1 )
                                  / 1024 + 1 ) * 1024 * 1024;
    system_specs.phys_mem = _go32_dpmi_remaining_physical_memory( );
    system_specs.virt_mem = _go32_dpmi_remaining_virtual_memory( );
    system_specs.total_mem = system_specs.phys_mem +
system_specs.virt_mem;

    /*
     * CMOS only reports up to 64MB, then wraps around, so we have to
     * see if the remaining physical memory is greater, and if so,
     * add the appropriate value.
     */
    if ( system_specs.phys_mem > system_specs.max_phys_mem )
        system_specs.max_phys_mem += ( system_specs.phys_mem /
                                       ( 65536 * 1024 ) ) + ( 65536 *
1024 );

    [more snipped...]
}

/*
 * Routines to return the amount of physical memory installed on the
host
 * computer.  Thanks to Eli Zaretskii for this code.
 */
static void usec_sleep( int usec )
{
    uclock_t start_time = uclock ();
    uclock_t end_time = start_time + UMAX(1, usec * UCLOCKS_PER_SEC /
1000000);
    
    while ( uclock () < end_time )
        ;
}


static unsigned char read_cmos( int reg )
{
    unsigned char al = ( reg & 0xff ) | 0x80;   /* disable NMI */
    
    outportb( 0x70, al );
    usec_sleep( 2 );            /* delay for 2 microseconds */
    al = inportb( 0x71 );
    usec_sleep( 2 );
    outportb( 0x70, 0 );        /* enable NMI */
    
    return al;
}


int installed_memory_size( void )
{
    unsigned base_lo, base_hi, ext_lo, ext_hi;
    
    base_lo = read_cmos( 0x15 );
    base_hi = read_cmos( 0x16 );
    ext_lo  = read_cmos( 0x17 );
    ext_hi  = read_cmos( 0x18 );
    
    return ( (base_hi + ext_hi) << 8 ) + base_lo + ext_lo;
}

-snip-
-- 
---------------------------------------------------------------------
| John M. Aldrich, aka Fighteer I  |        fighteer AT cs DOT com         |
| Call me for your free AOL disk!  |   http://www.cs.com/fighteer   |
|  Chain letters, work-at-home schemes, free long distance, etc.,   |
|    are ILLEGAL!  Keep the Internet litter-free... don't SPAM.     |
---------------------------------------------------------------------

- Raw text -


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