Determining system parameters

It is always a good thing to inform the user that his system is not capable of running your program. Well, the following message box could well do it for you:

I’ve seen programs that simply crashed or rebooted the system just because they haven’t done even the basic system tests. Using coprocessor when the computer doesn’t have one, using extended CPU instructions (MMX, 3D Now!, KNI) on processors that don’t support them is a shame. Shame on you, the programmer. I’ll show you here how to get some information on the system your program is running on so you can inform the user that your program requires a resource the computer is missing. Or even better, if you are skilled enough, silently accommodate to the new conditions (e.g. use different routines) so you won’t require the missing resources.

Testing for system main processor

Win32 API provides a function that will return information on the current computer system. See the provided example on how to use the API.

VOID GetSystemInfo( LPSYSTEM_INFO lpSystemInfo); 

However, you can write your own routine to check the type of the CPU. It is provided here and will return:

The routine is expected to run in a Win32 environment that won’t be available on anything less than a 386. It is written in assembly language simply because operations needed to determine CPU type can’t be written in C or C++.

static char CPUident[13]; 				
int whatCPU(void) {					
_asm {							
mov CPUident[12],0 // string describing CPU manufacturer
mov ebx,386 // starting with i386 			
pushfd							
pop eax							
mov ecx,eax						
mov edx,eax						
xor eax,40000h // 386 won’t change EFALGS bit 34	
push eax						
popfd							
pushfd							
pop eax							
xor eax,ecx						
je CPUexit						
add ebx,100						
mov eax,edx						
mov ecx,eax						
xor eax,200000h // most 486 won’t change EFALGS bit 37	
push eax // (that is, won’t support CPUID)		
popfd							
pushfd							
pop eax							
xor eax,ecx						
je CPUexit						
mov eax,0						
/* 586 specific code */					
cpuid // obtain CPU stepping from CPUID			
mov DWORD PTR [CPUident+0],ebx				
mov DWORD PTR [CPUident+4],edx				
mov DWORD PTR [CPUident+8],ecx				
mov eax,1						
cpuid							
xor ebx,ebx						
mov bl,ah						
mov eax,100						
mul ebx							
add eax,86						
mov ebx,eax						
CPUexit:						
mov eax,ebx						
}							
/* return eax; */					
}							

Testing for extended CPU instruction sets

There a 3 major instruction set extensions in IA (Intel Architecture) processors. They are:

If you use and/or require one of these first test for the presence of them. This routine will determine what CPU extensions are available and returns an array of flags in a doubleword value. If bit

int whatCPUExtensions(void) {				
__asm {							
mov edi,0						
pushfd							
pop eax							
mov edx,eax						
xor eax,200000h						
push eax						
popfd							
pushfd							
pop eax							
and eax,200000h						
and edx,200000h						
cmp eax,edx						
je ExtensionsEnd					
mov eax,1						
/* 586 specific code */					
cpuid							
test edx,00800000h  // Test bit 23, for MMX existence.	
je ExtensionsNoMMX					
or edi,1						
ExtensionsNoMMX:					
test edx, 02000000h // Test bit 25, for Streaming	
je ExtensionsNoKNI  //  SIMD Extensions existence.	
or edi,4						
ExtensionsNoKNI:					
mov eax,080000000h  // Test CPUID bit 32, for		
cpuid		    //  3DNow existence.		
test eax,eax						
jz ExtensionsEnd					
mov eax,080000001h					
cpuid							
test edx,080000000h					
je ExtensionsEnd					
or edi,2						
ExtensionsEnd:						
mov eax,edi						
}							
/* return eax; */					
}							

Testing for total and available memory

Win32 API provides a function that obtains information about the computer system's current usage of both physical and virtual memory. See the provided example on how to use the API.

VOID GlobalMemoryStatus( LPMEMORYSTATUS lpBuffer); 

Testing for DirectX

This routine fills in the DirectX version installed into the variable dxVersion. If

dxVersion = 0;					
char sVersion[32];				
>> Get Registry Value of "SOFTWARE\Microsoft\DirectX\Version" into sVersion <<
if (sVersion[0] != 0) {				
   char *dot0 = strchr(sVersion,'.');		
   if (dot0) {					
      char *dot1 = strchr(dot0+1,'.');		
      if (dot1) {				
	 char *dot2 = strchr(dot1+1,'.');	
	 if (dot2) {				
		// 4.05.00.0155			
		*dot2 = 0;			
		dxVersion = atol(dot1+1);	
		dxVersion += atol(dot0+1) << 16;
	 }					
      }						
   }						
}						

Sayza