From: "John M. Aldrich" Newsgroups: comp.os.msdos.djgpp Subject: Re: Programming Help Please Date: Thu, 09 Jan 1997 23:34:09 -0800 Organization: Two pounds of chaos and a pinch of salt Lines: 122 Message-ID: <32D5F0F1.2829@cs.com> References: <32D59523 DOT 5778 AT exis DOT net> Reply-To: fighteer AT cs DOT com NNTP-Posting-Host: ppp107.cs.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Joe Wright wrote: > > I need to know, programmatically, system memory size so that I can take > some action depending on more or less than 8 MB. I tried the int86() > approach and got 0K and also tried biosmemory() but got 640K. > If it is possible, can someone give me a snippet of code which will > report memory size? Thank you. 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 #include #include #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 | | Descent 2: The Infinite Abyss - The greatest Internet game of all | | time just got better! This time, you're going all the way down...| ---------------------------------------------------------------------