unit CPU;
interface
uses Types;
const
//Version Information bitmask BITMASK_ExtendedFamilyID=$0FF00000; BITMASK_ExtendedModelID= $000F0000; BITMASK_ProcessorType= $00003000; BITMASK_FamilyID= $00000F00; BITMASK_ModelID= $000000F0; BITMASK_SteppingID= $0000000F;
//Processor Type ProcessorType_OriginalOEMProcessor= $00000000; ProcessorType_IntelOverDriveProcessor= $00001000; ProcessorType_DualProcessor= $00002000; ProcessorType_IntelReserved= $00003000;
type
//register used in cpuid instruction TCPUIDRegister=packed record EAX:DWORD; case Integer of 0://register ( EBX:DWORD; ECX:DWORD; EDX:DWORD; ); 1://version information string ( VIS1:array[1..4] of Char; VIS2:array[1..4] of Char; VIS3:array[1..4] of Char; ); end;
PCPUIDRegister=^TCPUIDRegister;
//basic cupid information TCPUIDBasicInformation=packed record //EAX=0 HighestBasicProcessorInformationValue:Cardinal; VendorIdentificationString:string[12]; //EAX=1 ExtendedFamileyID, ExtendedModelID, ProcessorType, FamilyID, ModelID, SteppingID:DWORD; end;
PCPUIDBasicInformation=^TCPUIDBasicInformation;
TCPUInfo=class private fSupportForCPUID:Boolean; private function CPUID(Value:DWORD):TCPUIDRegister; function Get_CPUIDBasicInformation:TCPUIDBasicInformation; public constructor Create; public property SupportForCPUID:Boolean read fSupportForCPUID; property CPUIDBasicInformation:TCPUIDBasicInformation read Get_CPUIDBasicInformation; end;
implementation
uses Dialogs,SysUtils;
{ TCPUInfo }
function TCPUInfo.CPUID(Value:DWORD): TCPUIDRegister; var VEAX,VEBX,VECX,VEDX:DWORD; begin asm pushad mov eax,Value cpuid mov VEAX,eax mov VEBX,ebx mov VECX,ecx mov VEDX,edx popad end; with Result do begin EAX:=VEAX; EBX:=VEBX; ECX:=VECX; EDX:=VEDX; end; end;
constructor TCPUInfo.Create; const EF_ID:DWORD=$200000; var EFID:DWORD; begin fSupportForCPUID:=False; asm //save current register pushad //move old eflags to ebx pushfd pop eax //move old eflags to ebx mov ebx,eax //revert EF_ID xor eax,EF_ID push eax popfd //move new eflags to eax pushfd pop eax //test EF_ID xor eax,ebx mov EFID,eax //restore register popad end; if (EFID xor EF_ID)=0 then fSupportForCPUID:=True; end;
function TCPUInfo.Get_CPUIDBasicInformation: TCPUIDBasicInformation; var CPUIDRegister:TCPUIDRegister; begin CPUIDRegister:=CPUID(0); with CPUIDRegister,Result do begin HighestBasicProcessorInformationValue:=EAX; VendorIdentificationString:=VIS1+VIS3+VIS2; end; CPUIDRegister:=CPUID(1); with CPUIDRegister,Result do begin ExtendedFamileyID:=EAX and BITMASK_ExtendedFamilyID; ExtendedModelID:=EAX and BITMASK_ExtendedModelID; ProcessorType:=EAX and BITMASK_ProcessorType; FamilyID:=EAX and BITMASK_FamilyID; ModelID:=EAX and BITMASK_ModelID; SteppingID:=EAX and BITMASK_SteppingID; end; end;
end.