// this unit can be used to detect the cpu model.
Unit cpuid;
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: bolean;
Function checkamd3dnowplus: boolean;
Function getMaxExtendededfunctions: dword;
Procedure getExtendedfms (var family, model, step: byte);
Function getExtendedcpuname: string;
Function getExtendedl1dcache: Word;
Function getExtendedl1icache: Word;
Function getExtendedl2cache: Word;
Function Checkceleron: Boolean;
Function CheckpingUMIIII: Boolean;
Function Checkxeon: Boolean;
Function CheckpingUM4: Boolean;
Function Checkithanium: Boolean;
Function intelP5n: String;
Function intel6n: String;
Function AMDK5N: String;
Function Cyrix686n: String;
Function genericcpun: String;
Function P5cachel1Di: Word;
Function P6cachel1di: Word;
Function P6cachel2: Word;
Function Authenticamd: 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: = (Tempdtect = $ 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;
Const
Timeperiod = 1000;
VAR
Highfreq, Testfreq, Count1, Count2: INT64;
TimeStart: Integer;
TimeStop: integer;
ElapsedTime: DWORD;
StartTicks: DWORD;
EndTicks: DWORD;
TotalTicks: DWORD;
Begin
StartTicks: = 0;
Endticks: = 0; if QueryperFormanceFrequency (Highfreq) THEN BEGIN
Testfreq: = Highfreq Div 100;
QueryperFormanceCounter (count1);
Repeat
QueryperFormanceCounter (count2);
Until count1 <> count2;
ASM
Push EBX
XOR EAX, EAX
XOR EBX, EBX
XOR ECX, ECX
XOR EDX, EDX
DB $ 0F, $ A2 /// CPUID
DB $ 0F, $ 31 /// RDTSC
Mov StartTicks, EAX
POP EBX
END;
Repeat
QueryperFormanceCounter (count1);
Until count1-count2> = testfreq;
ASM
Push EBX
XOR EAX, EAX
XOR EBX, EBX
XOR ECX, ECX
XOR EDX, EDX
DB $ 0F, $ A2 /// CPUID
DB $ 0F, $ 31 /// RDTSC
Mov endticks, EAX
POP EBX
END;
ElapsedTime: = Muldiv (count1-count2, 1000000, highfreq);
end
Else Begin
TimeBeginperiod (1);
TimeStart: = TimegetTime;
Repeat
TimeStop: = TimegetTime;
Until TimeStop <> TimeStart;
ASM
Push EBX
XOR EAX, EAX
XOR EBX, EBX
XOR ECX, ECX
XOR EDX, EDX
DB $ 0F, $ A2 /// CPUID
DB $ 0F, $ 31 /// RDTSC
Mov StartTicks, EAX
POP EBX
END;
Repeat
TimeStart: = TimegetTime;
Until TimeStart-TimeStop> = TimePeriod;
ASM
Push EBX
XOR EAX, EAX
XOR EBX, EBX
XOR ECX, ECX
XOR EDX, EDX
DB $ 0F, $ A2 /// CPUID
DB $ 0F, $ 31 /// RDTSC
Mov endticks, EAX
POP EBX
END;
TimeEndPeriod (1);
ELAPSEDTIME: = (TimeStart-TimeStop) * 1000;
END;
Totalticks: = endticks-startticks;
Result: = Totalticks Div Elapsedtime;
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: = steppping (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);
Function TCPudata.checkmps: boolean;
Var sysinfo: tsysteminfo;
Begin
GetSystemInfo (sysinfo);
Checkmps: = (sysinfo.dwnumberofprocessors> 1);
END;
Function tcpudata.getnocpus: cardinal
Var sysinfo: tsysteminfo;
Begin
GetSystemInfo (sysinfo);
Getnocpus: = sysinfo.dwnumberofprocessors;
END;
Function TCPudata.checkpn: boolean;
Label NOPN;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 40000
JZ NOPN
Mov EDX, 0
Mov TempCheck, EDX
NOPN:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkpn: = (TempCheck = 0);
END;
Function tcpudata.checkcmpxchg8b: boolean;
Label NOCMPXCHG8B;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 100
JZ NOCMPXCHG8B
Mov EDX, 0
Mov TempCheck, EDX
NOCMPXCHG8B:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkcmpxchg8b: = (TempCheck = 0);
END;
Function TCPudata.checkcmove: Boolean;
Label NOCMOVE;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 8000
JZ NOCMOVE
Mov EDX, 0
Mov TempCheck, EDX
NOCMOVE:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkcmove: = (TempCheck = 0);
END;
Function tcpudata.checkselfsnoop: boolean;
Label noselfsnoP;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 8000000
JZ NoselfsnoP
Mov EDX, 0
Mov TempCheck, EDX
Noselfsnoop:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkselfsnoop: = (TempCheck = 0);
END;
Function TCPudata.checkdebugtracestore: Boolean;
Label NodebugtraceStore;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 200,000
JZ NodebugtraceStore
Mov EDX, 0
Mov TempCheck, EDX
NodebugtraceStore:
POP EDX
POP ECX
POP EBX
POP EAX
END;
CheckdebugtraceStore: = (TempCheck = 0);
END;
Function tcpudata.checkfxsavefxrs: boolean;
Label NofxSavefxrstor;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 1000000
JZ NofxSavefxrstor
Mov EDX, 0
Mov TempCheck, EDX
NofxSavefxrstor:
POP EDX
POP ECX
POP EBX
POP EAX
END;
CheckfxSavefxrstor: = (TempCheck = 0);
END;
Function tcpudata.checkmmmx: boolean;
Label Nommx;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 800000
JZ Nommx
Mov EDX, 0
Mov TempCheck, EDX
Nommx:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkmmx: = (TempCheck = 0);
END;
Function tcpudata.checkmmmxplus: bolean;
Label NommxPlus;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov Eax, $ 80000001
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 400000
JZ NommxPlus
Mov EDX, 0
Mov TempCheck, EDX
Nommxplus:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkmmxplus: = (TempCheck = 0);
END;
Function TCPudata.checksse: boolean;
Label Nosse;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 2000000
JZ Nossemov EDX, 0
Mov TempCheck, EDX
Nosse:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checksse: = (TempCheck = 0);
END;
Function TCPudata.checksse2: bolean;
Label Nosse2;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 4000000
JZ Nosse2
Mov EDX, 0
Mov TempCheck, EDX
Nosse2:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checksse2: = (TempCheck = 0);
END;
Function tcpudata.checkamd3dnow: boolean;
Label noamd3dnow;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov Eax, $ 80000001
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 80000000
JZ NOAMD3DNOW
Mov EDX, 0
Mov TempCheck, EDX
NoAmd3DNow:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkamd3dNow: = (TempCheck = 0);
END;
Function tcpudata.checkamd3dnowplus: boolean;
Label noamd3dnowplus;
Var TempCheck: DWORD;
Begin
TempCheck: = 1;
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov Eax, $ 80000001
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
Test EDX, $ 40000000
JZ NOAMD3DNOWPLUS
Mov EDX, 0
Mov TempCheck, EDX
NoAmd3DNowPlus:
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkamd3DNowPlus: = (TempCheck = 0);
END;
Function TCPudata.getMaxExtendedfunctions: DWORD;
Var Tempext: DWORD;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov EAX, $ 80000000
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
SHL EAX, 1
SHR EAX, 1
Mov Tempext, EAX
POP EDX
POP ECX
POP EBX
POP EAX
END;
GetMaxExtendedfunctions: = Tempext;
END;
Procedure tcpudata.getextendedfms (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, $ 80000001
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
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: = steppping (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.getextendedcpuname: string;
Var S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12: Array [0..3] of char;
Tempcpuname: String;
i: integer;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov EAX, $ 80000002
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
MOV S1, EAX
MOV S2, EBX
MOV S3, ECX
MOV S4, EDX
Mov EAX, $ 80000003
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
MOV S5, EAX
MOV S6, EBX
MOV S7, ECX
MOV S8, EDX
Mov EAX, $ 80000004
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
Mov S9, EAX
MOV S10, EBX
MOV S11, ECX
MOV S12, EDX
POP EDX
POP ECX
POP EBX
POP EAX
END;
Tempcpuname: = '';
For i: = 0 to 3 do
Tempcpuname: = TempcPuname S1 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S2 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S3 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S4 [i];
For i: = 0 to 3 dotempcpuname: = Tempcpuname S5 [i];
For i: = 0 to 3 do
Tempcpuname: = TempcPuname S6 [i];
For i: = 0 to 3 do
Tempcpuname: = TempcPuname S7 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S8 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S9 [i];
For i: = 0 to 3 do
TempcPuname: = TempcPuname S10 [i];
For i: = 0 to 3 do
Tempcpuname: = TempcPuname S11 [i];
For i: = 0 to 3 do
Tempcpuname: = TempcPuname S12 [i];
GetExtendedcpuname: = TempcPuname;
END;
Function TCPudata.getextendedl1dcache: Word;
Var L1D, Templ1d: DWORD;
BinArray: array [0..31] of byte;
I, P: Integer;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov Eax, $ 80000005
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
MOV L1D, ECX
POP EDX
POP ECX
POP EBX
POP EAX
END;
For i: = 0 to 31 do
Begin
BinArray [I]: = L1D MOD 2;
L1D: = L1D DIV 2;
END;
Templ1d: = 0;
P: = 0;
For i: = 24 to 31 do
Begin
Templ1d: = Templ1D (binaRray [i] * start (floattostr (Power (2, p))))
INC (P);
END;
GetExtendedl1dcache: = Templ1d;
END;
Function TCPudata.getextendedl1icacche: Word;
Var L1i, Templ1i: DWORD;
BinArray: array [0..31] of byte;
I, P: Integer;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
Mov Eax, $ 80000005
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
MOV L1i, EDX
POP EDX
POP ECX
POP EBX
POP EAX
END;
For i: = 0 to 31 do
Begin
BinArray [I]: = L1i MOD 2;
L1i: = L1I Div 2;
END;
Templ1i: = 0;
P: = 0;
For i: = 24 to 31 do
Begin
Templ1i: = Templ1i (binaRray [i] * start (floattostr (Power (2, P))))
INC (P);
END;
GetExtendedl1icache: = Templ1i;
END;
Function TCPudata.getextendedl2cache: Word; Var L2, Templ2: DWORD
BinArray: array [0..31] of byte;
I, P: Integer;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV EAX, $ 80000006
MOV EBX, 0
MOV ECX, 0
Mov EDX, 0
DB $ 0F, $ A2 /// CPUID
MOV L2, ECX
POP EDX
POP ECX
POP EBX
POP EAX
END;
For i: = 0 to 31 do
Begin
Binarray [I]: = L2 MOD 2;
L2: = L2 DIV 2;
END;
TEMPL2: = 0;
P: = 0;
For i: = 16 to 31 do
Begin
Templ2: = Templ2 (binaRray [i] * STRTOINT (Floattostr (Power (2, P))))
INC (P);
END;
GetExtendedl2cache: = Templ2;
END;
Function TCPudata.checkceleron: boolean;
VAR BID: BYTE;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
MOV BID, BL
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkceleron: = (BID = $ 1);
END;
Function TCPudata.checkping TCPUDATA.CHECKPENTIUMIIIII: Boolean;
VAR BID: BYTE;
Begin
If Checkmmmmx and Checksse the CHECKPENTIUMIIIIII: = TRUE
Else Checkpentiumiiiii: = false;
END;
Function tcpudata.checkxeon: bolean;
VAR BID: BYTE;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
MOV BID, BL
POP EDX
POP ECX
POP EBX
POP EAX
END;
Checkxeon: = (BID = $ 3);
END;
Function TCPudata.checkping TCPUDATA.CHECKPENTIUM4: BOOLEAN;
VAR BID: BYTE;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
MOV BID, BL
POP EDX
POP ECX
POP EBX
POP EAX
END;
CheckpingUM4: = (BID = $ 8);
END;
Function TCPudata.checkithanium: Boolean;
Var res: dword;
BinArray: array [0..31] of byte;
i: byte;
Begin
ASM
Push EAX
Push EBX
Push ECX
Push Edx
MOV Eax, 1
DB $ 0F, $ A2 /// CPUID
Mov Res, EDX
POP EDX
POP ECX
POP EBX
POP EAX
END;
For i: = 0 to 31 do
Begin
BinArray [I]: = RES MOD 2;
RES: = RES DIV 2;
END;
Checkithanium: = (CHECKPENTIUM4 AND (BINARRAY [30] = 1);
END;
Function tcpudata.intelp5n: string;
Begin
If Checkmmmmx Then Intelp5n: = 'Intel Pentium (R) MMX (TM)'
Else Intelp5n: = 'Intel Pentium (R)';
END;
Function tcpudata.intelp6n: string;
Begin
If Checkceleron Then Intelp6n: = 'Intel Celeron (R)'
Else
If Checkping THENIIIIIIIIIIIIIIIII THENITIUM (R) III '
Else
If Checkxeon Then Intelp6N: = 'Intel Pentium (R) III Xeon (TM)'
Else
IF not checkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Else Intelp6n: = 'Intel Pentium (R) II';
END;
Function tcpudata.amdk5n: string;
Var Family, Model, Stepping: Byte
Begin
Getfms (Family, Model, Stepping);
IF model = 0 Then AMDK5N: = 'AMD K5'
Else AMDK5N: = getExtendedcpuname
END;
Function tcpudata.cyrix686n: string;
Begin
If CPudata.getMaxExtendedfunctions> 0 Then Cyrix686n: = getExtendedcpuname
Else
If Checkmmmx Then Cyrix686N: = 'VIA Cyrix 6x86mii'
Else
Cyrix686n: = 'VIA Cyrix 6x86';
END;
Function TCPudata.Genericcpun: String;
Var sysinfo: tsysteminfo;
Begin
GetSystemInfo (sysinfo);
IF sysinfo.dwprocessortype = 386
Then genericcpun: = 'Generic 386 CPU'
Else
IF sysinfo.dwprocessortype = 486
Then genericcpun: = 'Generic 486 CPU'
Else
IF sysinfo.dwprocessortype = 586
Then genericcpun: = 'Pentium Class CPU'
Else Genericcpun: = 'UNKNOWN CPU';
END;
Function TCPudata.p5cachel1di: Word;
Begin
IF CHECKMMX THEN P5CACHEL1DI: = 16
Else P5cachel1di: = 8;
END;
Function TCPudata.p6cachel1di: Word;
Begin
IF not checkmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
Else P6cachel1di: = 16;
Function tcpudata.p6cachel2: word;
Var Family, Model, Stepping: Byte
Begin
IF CHECKCELERON THEN P6CACHEL2: = 128
Else
IF Checkping THEN BEGIN
Getfms (Family, Model, Stepping);
if model = 7 THEN P6Cachel2: = 512
Else if model = 8 THEN P6Cachel2: = 256
ELSE P6Cachel2: = 512;
end
else if not CheckMMX then P6CacheL2: = 512
ELSE P6Cachel2: = 512;
END;
Function tcpudata.authenticamd: tcpurec;
Var Family, Model, Stepping: Byte
EFAMILY, Emodel, Estepping: BYTE
Begin
Getfms (Family, Model, Stepping);
IF family = 4 THEN Begin
Authenticamd.name:='AMD 486 ';
Authenticamd.vendor: = getvendorstring;
Authenticamd.frequency: = 0;
Authenticamd.family :=family;
Authenticamd.model: = model;
Authenticamd.stepping: = step;
Authenticamd.l1dcache: = 8;
Authenticamd.l1icache: = 8;
Authenticamd.l2cache: = 0;
end
Else
IF family = 5 THEN Begin
IF getMaxExtendedfunctions> 4 THEN
Begin
Authenticamd.name:=getextendedcpuname;
Authenticamd.vendor: = getvendorstring;
AUThenticamd.frequency: = getcpufrequency;
GetExtendedfms (Efamily, Emodel, Estepping);
Authenticamd.family:=efamily;
Authenticamd.model: = Emodel;
Authenticamd.stepping: = estepping;
Authenticamd.l1dcache: = getextendedl1dcache;
Authenticamd.l1icache: = getExtendedl1icache;
Authenticamd.l2cache: = 0;
end
Else
Begin
Authenticamd.name:=amdk5n;
Authenticamd.vendor: = getvendorstring;
AUThenticamd.frequency: = getcpufrequency;
Authenticamd.family :=family;
Authenticamd.model: = model;
Authenticamd.stepping: = step;
Authenticamd.l1dcache: = 16;
Authenticamd.l1icache: = 16;
Authenticamd.l2cache: = 0;
END;
end
Else IF Family> 5 Thenbegin
Authenticamd.name:=getextendedcpuname;
Authenticamd.name:=getextendedcpuname;
Authenticamd.vendor: = getvendorstring;
AUThenticamd.frequency: = getcpufrequency;
GetExtendedfms (Efamily, Emodel, Estepping);
Authenticamd.family:=efamily;
Authenticamd.model: = Emodel;
Authenticamd.stepping: = estepping;
Authenticamd.l1dcache: = getextendedl1dcache;
Authenticamd.l1icache: = getExtendedl1icache;
Authenticamd.l2cache: = getextendedl2cache;
END;
END;
Function tcpudata.genuineintel: tcpurec;
Var Family, Model, Stepping: Byte
Begin
Getfms (Family, Model, Stepping);
IF family = 4 THEN Begin
Genuineintel.name:=intel 486 ';
Genuineintel.vendor: = getvendorstring;
Genuineintel.frequency: = 0;
Genuineintel.family :=family;
Genuineintel.model: = model;
Genuineintel.stepping: = stepback;
Genuineintel.l1dcache: = 8;
Genuineintel.l1icache: = 8;
Genuineintel.l2cache: = 0;
end
Else
IF family = 5 THEN Begin
Genuineintel.name:=intelp5n;
Genuineintel.vendor: = getvendorstring;
Genuineintel.frequency: = getcpufrequency;
Genuineintel.family :=family;
Genuineintel.model: = model;
Genuineintel.stepping: = stepback;
Genuineintel.l1dcache: = p5cachel1di;
Genuineintel.l1icacche: = p5cachel1di;
Genuineintel.l2cache: = 0;
end
Else
IF family = 6 THEN Begin
Genuineintel.name:=intelp6n;
Genuineintel.vendor: = getvendorstring;
Genuineintel.frequency: = getcpufrequency;
Genuineintel.family :=family;
Genuineintel.model: = model;
Genuineintel.stepping: = stepback;
Genuineintel.l1dcache: = p6cachel1di;
Genuineintel.l1icache: = p6cachel1di;
Genuineintel.l2cache: = p6cachel2;
end
Else
IF family = $ f Then Beginif checkpersing
Begin
Genuineintel.name:= Setel Pentium (R) 4 ';
Genuineintel.vendor: = getvendorstring;
Genuineintel.frequency: = getcpufrequency;
Genuineintel.family :=32;
Genuineintel.model: = model;
Genuineintel.stepping: = stepback;
Genuineintel.l1dcache: = 8;
Genuineintel.l1icache: = 12;
Genuineintel.l2cache: = 256;
end
Else if Checkithanium Then
Begin
Genuineintel.name:=intel ithanium ';
Genuineintel.vendor: = getvendorstring;
Genuineintel.frequency: = getcpufrequency;
Genuineintel.family :=64;
Genuineintel.model: = model;
Genuineintel.stepping: = stepback;
Genuineintel.l1dcache: = 0;
Genuineintel.l1icacche: = 0;
Genuineintel.l2cache: = 0;
END;
END;
END;
Function TCPUDATA.CYRIXINSTEAD: TCPUREC;
Var Family, Model, Stepping: Byte
EFAMILY, Emodel, Estepping: BYTE
Begin
Getfms (Family, Model, Stepping);
IF family = 4 THEN Begin
Cyrixinstead.name:=Via Cyrix 4x86 ';
Cyrixinstead.vendor: = getvendorstring;
Cyrixinstead.frequency: = 0;
Cyrixinstead.family :=family;
Cyrixinstead.model: = model;
CYRIXINSTEAD.STEPPING: = step;
CYRIXINSTEAD.L1DCACHE: = 8;
Cyrixinstead.l1icache: = 8;
CYRIXINSTEAD.L2CACHE: = 0;
end
Else
IF family = 5 THEN Begin
Cyrixinstead.name:='VIA Cyrix 5x86 ';
Cyrixinstead.vendor: = getvendorstring;
CYRIXINSTEAD.FREQUENCY: = getcpufrequency;
Cyrixinstead.family :=family;
Cyrixinstead.model: = model;
CYRIXINSTEAD.STEPPING: = step;
CYRIXINSTEAD.L1DCACHE: = 8;
Cyrixinstead.l1icache: = 8;
CYRIXINSTEAD.L2CACHE: = 0;
end
Else Begin
IF getMaxExtendedfunctions> 0 THEN
Begin
Cyrixinstead.name:=getextendededcpuname; phyrixinstead.vendor:=getvendorstring;
CYRIXINSTEAD.FREQUENCY: = getcpufrequency;
GetExtendedfms (Efamily, Emodel, Estepping);
Cyrixinstead.family ;=efamily;
Cyrixinstead.model: = Emodel;
Cyrixinstead.stepping: = estepping;
Cyrixinstead.l1dcache: = getExtendedl1dcache;
Cyrixinstead.l1icache: = getextendedl1icache;
Cyrixinstead.l2cache: = getextendedl2cache;
end
Else Begin
Cyrixinstead.name:=Cyrix686n;
Cyrixinstead.vendor: = getvendorstring;
CYRIXINSTEAD.FREQUENCY: = getcpufrequency;
Cyrixinstead.family :=family;
Cyrixinstead.model: = model;
CYRIXINSTEAD.STEPPING: = step;
Cyrixinstead.l1dcache: = 32;
Cyrixinstead.l1icache: = 32;
CYRIXINSTEAD.L2CACHE: = 0;
END;
END;
END;
Function TCPudata.Genericcpu: TCPurec;
Var Family, Model, Stepping: Byte
EFAMILY, Emodel, Estepping: BYTE
Begin
IF not getcpuidsupport the
Begin
Messagedlg ('this cpu does not support the cpuid instruction !!!', MTWARNING,
[MBOK], 0);
Genericcpu.name:=unidentified CPU ';
Genericcpu.vendor: = 'unidentified';
Genericcpu.frequency: = 0;
Genericcpu.family :=-1;
Genericcpu.model: = - 1;
Genericcpu.stepping: = - 1;
Genericcpu.l1dcache: = 0;
Genericcpu.l1icache: = 0;
Genericcpu.l2cache: = 0;
end
Else
Begin
Getfms (Family, Model, Stepping);
IF getMaxExtendedfunctions> 0 THEN
Begin
Genericcpu.name:=getextendededcpuname;
Genericcpu.vendor: = getvendorstring;
Genericcpu.frequency: = getcpufrequency;
Cpudata.Getextendedfms (eFamily, Emodel, Estepping);
Genericcpu.family :=efamily;
Genericcpu.model: = EFAMILY;
Genericcpu.stepping: = estepping;
Genericcpu.l1dcache: = getExtendedl1dcache;
Genericcpu.l1icache: = getExtendedl1icache; genericcpu.l2cache: = getextendedl2cache
end
Else Begin
Genericcpu.name:=Genericcpun;
Genericcpu.vendor: = getvendorstring;
IF Family <= 4 Then genericcpu.frequency: = 0
Else genericcpu.frequency: = getcpufrequency;
Genericcpu.family:=Family;
Genericcpu.model: = model
Genericcpu.stepping: = step;
Genericcpu.l1dcache: = 0;
Genericcpu.l1icache: = 0;
Genericcpu.l2cache: = 0;
END;
END;
END;
End.