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.