unit CPU;
interface
uses Windows, Mmsystem, Sysutils, Math, Dialogs;
type
TCpuRec=record
Name:string[128];
Vendor:string[12];
Frequency:word;
Family:integer;
Model:integer;
Stepping:integer;
L1DCache:word;
L1ICache:word;
L2Cache:word;
end;
TCpuType = (cpu8086, cpu286, cpu386, cpu486, cpuPentium);
TCpuData=object
function GetCPUIDSupport:Boolean;
function GetVendorString:string;
function GetCPUFrequency:word;
procedure GetFMS(var Family,Model,Stepping:byte);
function GetMaxCpuId:dword;
function CheckFPU:Boolean;
function CheckTSC:Boolean;
function CheckMSR:Boolean;
function CheckMPS:Boolean;
function GetNoCpus:cardinal;
function CheckPN:Boolean;
function CheckCMPXCHG8B:Boolean;
function CheckCMOVe:Boolean;
function CheckSelfSnoop:Boolean;
function CheckDebugTraceStore:Boolean;
function CheckFXSAVEFXRSTOR:Boolean;
function CheckMMX:Boolean;
function CheckMMXplus:Boolean;
function CheckSSE:Boolean;
function CheckSSE2:Boolean;
function CheckAMD3DNow:Boolean;
function CheckAMD3DNowPlus:Boolean;
function GetMaxExtendedFunctions:dword;
procedure GetExtendedFMS(var Family,Model,Stepping:byte);
function GetExtendedCpuName:string;
function GetExtendedL1DCache:word;
function GetExtendedL1ICache:word;
function GetExtendedL2Cache:word;
function CheckCeleron:Boolean;
function CheckPentiumIII:Boolean;
function CheckXeon:Boolean;
function CheckPentium4:Boolean;
function CheckIthanium:Boolean;
//****Aici am conrectat****
function IntelP5N:string;
function IntelP6N:string;
//****Pana aici****
function AMDK5N:string;
function Cyrix686N:string;
function GenericCpuN:string;
function P5CacheL1DI:word;
function P6CacheL1DI:word;
function P6CacheL2:word;
function AuthenticAMD:TCpuRec;
function GenuineIntel:TCpuRec;
function CyrixInstead:TCpuRec;
function GenericCPU:TCpuRec;
end;
const
Intel486:array[0..8] of string=
('Intel 486 DX',
'Intel 486 DX',
'Intel 486 SX',
'Intel 486 DX2',
'Intel 486 SL',
'Intel 486 SX2',
'Intel 486 DX2',
'Intel 486 DX4',
'Intel 486 DX4');
UMC486:array[0..1] of string=
('UMC U5D',
'UMC U5S');
AMD486:array[0..5] of string=
('AMD 486 DX2',
'AMD 486 DX2',
'AMD 486 DX4',
'AMD 486 DX4',
'AMD 5x86',
'AMD 5x86');
IntelP5:array[0..6] of string=
('Intel Pentium P5 A-Step',
'Intel Pentium P5',
'Intel Pentium P54C',
'Intel Pentium P24T Overdrive',
'Intel Pentium MMX P55C',
'Intel Pentium P54C',
'Intel Pentium MMX P55C');
NexGenNx586='NexGen Nx586';
Cyrix4x86='VIA Cyrix 4x86';
Cyrix5x86='VIA Cyrix 5x86';
CyrixMediaGX='VIA Cyrix Media GX';
CyrixM1='VIA Cyrix 6x86';
CyrixM2='VIA Cyrix 6x86MX';
CyrixIII='VIA Cyrix III';
AMDK5:array[0..3] of string=
('AMD SSA5 (PR75/PR90/PR100)',
'AMD 5k86 (PR120/PR133)',
'AMD 5k86 (PR166)',
'AMD 5k86 (PR200)');
AMDK6:array[0..4] of string=
('AMD K6 (166~233)',
'AMD K6 (266~300)',
'AMD K6-2',
'AMD K6-III',
'AMD K6-2+ or K6-III+');
Centaur:array[0..2] of string=
('Centaur C6',
'Centaur C2',
'Centaur C3');
Rise:array[0..1] of string=
('Rise mP6',
'Rise mP6');
IntelP6:array[0..7] of string=
('Intel Pentium Pro A-Step',
'Intel Pentium Pro',
'Intel Pentium II',
'Intel Pentium II',
'Intel Pentium II',
'Intel Pentium III',
'Intel Pentium III',
'Intel Pentium III');
AMDK7:array[0..3] of string=
('AMD Athlon(tm) Processor',
'AMD Athlon(tm) Processor',
'AMD Duron(tm) Processor',
'AMD Thunderbird Processor');
IntelP4='Intel Pentium 4';
var CpuData:TCpuData;
implementation
function TCpuData.GetCPUIDSupport:Boolean;
var TempDetect:dword;
begin
asm
pushf
pushfd
push eax
push ebx
push ecx
push edx
pushfd
pop eax
mov ebx,eax
xor eax,$00200000
push eax
popfd
pushfd
pop eax
push ebx
popfd
xor eax,ebx
mov TempDetect,eax
pop edx
pop ecx
pop ebx
pop eax
popfd
popf
end;
GetCPUIDSupport:=(TempDetect=$00200000);
end;
function TCpuData.GetVendorString:string;
var s1,s2,s3:array[0..3] of char;
TempVendor:string;
i:integer;
begin
asm
push eax
push ebx
push ecx
push edx
mov eax,0
db $0F,$A2 /// cpuid
mov s1,ebx
mov s2,edx
mov s3,ecx
pop edx
pop ecx
pop ebx
pop eax
end;
TempVendor:='';
for i:=0 to 3 do
TempVendor:=TempVendor+s1[i];
for i:=0 to 3 do
TempVendor:=TempVendor+s2[i];
for i:=0 to 3 do
TempVendor:=TempVendor+s3[i];
GetVendorString:=TempVendor;
end;
function TCpuData.GetCPUFrequency:word;
var TimeStart:integer;
TimeStop:integer;
StartTicks:dword;
EndTicks:dword;
TotalTicks:dword;
cpuSpeed:dword;
NeverExit:Boolean;
begin
TimeStart:=0;
TimeStop:=0;
StartTicks:=0;
EndTicks:=0;
TotalTicks:=0;
cpuSpeed:=0;
NeverExit:=True;
TimeStart:=timeGetTime;
while NeverExit do
begin
TimeStop:=timeGetTime;
if ((TimeStop-TimeStart)>1) then
begin
asm
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 /// cpuid
db $0F,$31 /// rdtsc
mov StartTicks,eax
end;
Break;
end;
end;
TimeStart:=TimeStop;
while NeverExit do
begin
TimeStop:=timeGetTime;
if ((TimeStop-TimeStart)>1000) then
begin
asm
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
db $0F,$A2 /// cpuid
db $0F,$31 /// rdtsc
mov EndTicks,eax
end;
Break;
end;
end;
TotalTicks:=EndTicks-StartTicks;
cpuSpeed:=TotalTicks div 1000000;
GetCPUFrequency:=cpuSpeed;
end;
procedure TCpuData.GetFMS(var Family,Model,Stepping:byte);
var TempFlags:dword;
BinFlags:array[0..31] of byte;
i,pos:integer;
begin
asm
push eax
push ebx
push ecx
push edx
mov eax,1
db $0F,$A2 /// cpuid
mov TempFlags,eax
pop edx
pop ecx
pop ebx
pop eax
end;
for i:=0 to 31 do
begin
BinFlags[i]:=TempFlags mod 2;
TempFlags:=TempFlags div 2;
end;
family:=0;
model:=0;
stepping:=0;
pos:=0;
for i:=0 to 3 do
begin
stepping:=stepping+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i))));
inc(pos);
end;
pos:=4;
for i:=0 to 3 do
begin
model:=model+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i))));
inc(pos);
end;
pos:=8;
for i:=0 to 3 do
begin
family:=family+(BinFlags[pos]*StrToInt(FloatToStr(Power(2,i))));
inc(pos);
end;
end;
function TCpuData.GetMaxCpuId:dword;
var TempMax:dword;
begin
asm
push eax
push ebx
push ecx
push edx
mov eax,0
db $0F,$A2 /// cpuid
mov TempMax,eax
pop edx
pop ecx
pop ebx
pop eax
end;
GetMaxCpuId:=TempMax;
end;
function TCpuData.CheckFPU:Boolean;
label NoFpu;
var TempCheck:dword;
begin
TempCheck:=1;
asm
push eax
push ebx
push ecx
push edx
mov eax,1
db $0F,$A2 /// cpuid
test edx,$1
jz NoFpu
mov edx,0
mov TempCheck,edx
NoFpu:
pop edx
pop ecx
pop ebx
pop eax
end;
CheckFpu:=(TempCheck=0);
end;
function TCpuData.CheckTSC:Boolean;
label NoTSC;
var TempCheck:dword;
begin
TempCheck:=1;
asm
push eax
push ebx
push ecx
push edx
mov eax,1
db $0F,$A2 /// cpuid
test edx,$10
jz NoTSC
mov edx,0
mov TempCheck,edx
NoTSC:
pop edx
pop ecx
pop ebx
pop eax
end;
CheckTSC:=(TempCheck=0);
end;
function TCpuData.CheckMSR:Boolean;
label NoMSR;
var TempCheck:dword;
begin
TempCheck:=1;
asm
push eax
push ebx
push ecx
push edx
mov eax,1
db $0F,$A2 /// cpuid
test edx,$20
jz NoMSR
mov edx,0
mov TempCheck,edx
NoMSR:
pop edx
pop ecx
pop ebx
pop eax
end;
CheckMSR:=(TempCheck=0);
end;