00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define WIN32_LEAN_AND_MEAN
00024 #pragma warning(disable : 4201 4214 4115)
00025 #include <windows.h>
00026 #include <string.h>
00027 #pragma warning(default : 4201 4214 4115; disable : 4514)
00028
00029 #include "CPUInfo.h"
00030
00031 #define CPUID _asm _emit 0fh _asm _emit 0a2h
00032
00033 static int Flag_CPUID = TRUE;
00034 static int Flag_RDTSC = TRUE;
00035
00036
00037 void Test_CPU_bits(void)
00038 {
00039 Flag_CPUID = FALSE;
00040 Flag_RDTSC = FALSE;
00041 _asm
00042 {
00043 pushad
00044 pushfd
00045 pop eax
00046 mov ebx,eax
00047
00048 xor eax,200000h
00049
00050 push eax
00051 popfd
00052 xor eax,ebx
00053
00054 jz done
00055 mov eax,1
00056 mov Flag_CPUID,eax
00057
00058 CPUID
00059 test edx,10h
00060 jz done
00061
00062 mov Flag_RDTSC,1
00063 done:
00064 popad
00065 }
00066 }
00067
00068
00069
00070
00071
00072 static uint32 CPUInfo_GetCPUIDEAX(uint32 funcNum)
00073 {
00074 uint32 retval;
00075
00076 Test_CPU_bits();
00077 if (Flag_CPUID)
00078 {
00079 __try
00080 {
00081 _asm
00082 {
00083 mov eax,funcNum
00084 CPUID
00085 mov retval,eax
00086 }
00087 }__except(EXCEPTION_EXECUTE_HANDLER)
00088 {
00089 retval =0;
00090 }
00091 }
00092 else
00093 {
00094 retval = 0;
00095 }
00096
00097 return retval;
00098 }
00099
00100 static uint32 CPUInfo_GetCPUIDEDX(uint32 funcNum)
00101 {
00102 uint32 retval;
00103
00104 Test_CPU_bits();
00105 if (Flag_CPUID)
00106 {
00107 __try
00108 {
00109 _asm
00110 {
00111 mov eax,funcNum
00112 CPUID
00113 mov retval,edx
00114 }
00115 }__except(EXCEPTION_EXECUTE_HANDLER)
00116 {
00117 retval =0;
00118 }
00119 }
00120 else
00121 {
00122 retval = 0;
00123 }
00124
00125 return retval;
00126 }
00127
00128
00129 static uint32 CPUInfo_GetCPUIDString(uint32 funcNum, char *szId)
00130 {
00131 uint32 retval;
00132
00133 Test_CPU_bits();
00134 if (Flag_CPUID)
00135 {
00136 __try
00137 {
00138 _asm
00139 {
00140 mov eax,funcNum
00141 CPUID
00142 mov retval,eax
00143 mov eax,szId
00144 mov dword ptr[eax],ebx
00145 mov dword ptr[eax+4],edx
00146 mov dword ptr[eax+8],ecx
00147 }
00148 }__except(EXCEPTION_EXECUTE_HANDLER)
00149 {
00150 retval =0;
00151 }
00152 }
00153 else
00154 {
00155 retval = 0;
00156 }
00157
00158 return retval;
00159 }
00160
00161
00162 #define CPUINFO_VENDOR_STRING_LENGTH 16
00163 #define CPUINFO_AMD_ID_STRING "AuthenticAMD"
00164 #define CPUINFO_INTEL_ID_STRING "GenuineIntel"
00165
00166 geBoolean CPUInfo_TestFor3DNow(void)
00167 {
00168 char VendorString[CPUINFO_VENDOR_STRING_LENGTH];
00169
00170 CPUInfo_GetCPUIDString(0, VendorString);
00171 if(strncmp(VendorString, CPUINFO_AMD_ID_STRING,strlen(CPUINFO_AMD_ID_STRING))==0)
00172 {
00173 uint32 TypeFlags =CPUInfo_GetCPUIDEAX(0x80000000);
00174 if(TypeFlags)
00175 {
00176 TypeFlags =CPUInfo_GetCPUIDEDX(0x80000001);
00177 if (TypeFlags & (1<<23))
00178 return GE_TRUE;
00179 }
00180 }
00181 return GE_FALSE;
00182 }
00183
00184 geBoolean CPUInfo_TestForMMX(void)
00185 {
00186 char VendorString[CPUINFO_VENDOR_STRING_LENGTH];
00187
00188 CPUInfo_GetCPUIDString(0, VendorString);
00189 if(strncmp(VendorString, CPUINFO_AMD_ID_STRING,strlen(CPUINFO_AMD_ID_STRING))==0)
00190 {
00191 uint32 TypeFlags =CPUInfo_GetCPUIDEAX(0x80000000);
00192 if(TypeFlags)
00193 {
00194 TypeFlags =CPUInfo_GetCPUIDEDX(0x80000001);
00195 if (TypeFlags & (1<<23))
00196 return GE_TRUE;
00197 }
00198 }
00199 else if(strncmp(VendorString, CPUINFO_INTEL_ID_STRING, strlen(CPUINFO_INTEL_ID_STRING))==0)
00200 {
00201 uint32 TypeFlags =CPUInfo_GetCPUIDEDX(0x1);
00202 if (TypeFlags & (1<<23))
00203 return GE_TRUE;
00204 }
00205
00206 return GE_FALSE;
00207 }