API - detectando se o chip eh Pentium, AMD e modelo (486, 686)

Top  Previous  Next

{

I recently upgraded my motherboard to a 233Mhz AMD processor.  I knew that you could provoke an Intel chip into returning

the text “GenuineIntel” in a series of registers so I was curious to know what the AMD chip would return.  The answer proved

to be the text “AuthenticAMD”: 

}

                     

 

// This bitmap was clipped from a simple form which just has two labels that are initialised in the FormCreate event handler: 

 

     procedure TForm1.FormCreate(Sender: TObject); 

     begin 

       Label1.Caption := 'Vendor: ' + VendorId; 

       Label2.Caption := 'Type: ' + IntToStr (CpuType) 

     end;

 

{

All you need to do to test this out is add the two lines above to your FormCreate, and add the CPUInfo unit to your Uses

clause. 

 

The VendorId and CpuType values are obtained using the CpuInfo unit listed below. Portions of this are based off of Intels

published information on obtaining CPU ID's: 

 

Enjoy! 

}

     // obtain information on the CPU 

 

     unit CpuInfo; 

 

     interface 

 

     type 

       TFeatures = record 

         case integer of 

           0: (RegEAX, 

               RegEBX, 

               RegEDX, 

               RegECX  : integer); 

           1 : (I : array [0..3of integer); 

           2 : (C : array [0..15of char); 

           3 : (B : array [0..15of byte) 

       end

 

     const 

     {$IFNDEF WIN32} 

       i8086       = 1// includes 8088/V20/V30/80186/80188 

       i80286      = 2

       i80386      = 3

     {$ENDIF} 

       i80486      = 4

       Chip486     = 4

       iPentium    = 5

       Chip586     = 5

       iPentiumPro = 6

       Chip686     = 6

 

     // known vendor id strings: 

       Intel = 'GenuineIntel'

       AMD   = 'AuthenticAMD'

 

     var 

       CpuType   : byte = 0;         // type of CPU 

       VendorId  : string [12]= '';  // contains vendor string 

       Features  : TFeatures;        // contains signature and feature information 

 

     procedure LoadFeatures (I : integer); 

 

     implementation 

 

     {$O-} 

     const 

       CpuId = $0a20f;  // hardcoded CpuId instruction 

                        // not supported by inline assembler 

     var 

       CpuIdFlag : boolean = false;  // true if CpuId instruction works 

       MaxCPUId  : integer;          // contains max value of eax value for CpuId instruction 

 

     // procedure to load features from CPUId instruction 

     // call with eax containing CPUId instruction number 

     procedure GetF; 

     asm 

              dw        CpuId           // Hardcoded CPUID instruction 

              mov       [Features.RegEAX], eax 

              mov       [Features.RegEBX], ebx 

              mov       [Features.RegECX], ecx 

              mov       [Features.RegEDX], edx 

     end

 

     // procedure to clear features record to zero 

     procedure ClearF; 

     asm 

              mov       edi, offset Features  // edi point at features record 

              xor       eax, eax              // clear eax 

              mov       ecx, eax 

              mov       cl, 4                 // 4 double words, 16 bytes 

              cld                             // forward direction 

              rep       stosd                 // do it 

     end

 

     // This procedure determines the type of processor in a system 

     // and sets the CpuType variable with the appropriate 

     // value. If the CPUID instruction is available, it is used 

     // to determine more specific details about the processor. 

     // All registers are used by this procedure, none are preserved. 

     // To avoid AC faults, the AM bit in CR0 must not be set. 

 

     procedure CheckOutCpu; 

     asm 

     {$IFNDEF WIN32} 

     // 8086 processor check 

     // Bits 12-15 of the FLAGS register are always set on the 

     // 8086 processor. 

              pushf                     // push original FLAGS 

              pop       ax              // get original FLAGS 

              mov       cx, ax          // save original FLAGS 

              and       ax, 0fffh       // clear bits 12-15 in FLAGS 

              push      ax              // save new FLAGS value on stack 

              popf                      // replace current FLAGS value 

              pushf                     // get new FLAGS 

              pop       ax              // store new FLAGS in AX 

              and       ax, 0f000h      // if bits 12-15 are set, then 

              cmp       ax, 0f000h      // processor is an 8086 

              mov       [CPUType], 1    // set flag to 8086/8088 

              je        @@2             // jump if processor is 8086/8088 

 

     // 286 processor check 

     // Bits 12-15 of the FLAGS register are always clear on the 

     // 286 processor in real-address mode. 

              or        cx, 0f000h      // try to set bits 12-15 

              push      cx              // save new FLAGS value on stack 

              popf                      // replace current FLAGS value 

              pushf                     // get new FLAGS 

              pop       ax              // store new FLAGS in AX 

              and       ax, 0f000h      // if bits 12-15 are clear 

              mov       [CPUType], 2    // processor=80286, turn on 80286 flag 

              jz        @@2             // if bits set, processor is 80286 

 

     // 386 processor check 

     // The AC bit, bit #18, is a new bit introduced in the EFLAGS 

     // register on the 486 processor to generate alignment faults. 

     // This bit cannot be set on the Intel386 processor. 

              pushfd                    // push original EFLAGS 

              pop       eax             // get original EFLAGS 

              mov       ecx, eax        // save original EFLAGS 

              xor       eax, 40000h     // flip AC bit in EFLAGS 

              push      eax             // save new EFLAGS value on stack 

              popfd                     // replace current EFLAGS value 

              pushfd                    // get new EFLAGS 

              pop       eax             // store new EFLAGS in EAX 

              xor       eax, ecx        // can't toggle AC bit, processor=80386 

              mov       [CPUType], 3    // turn on 80386 processor flag 

              jz        @@2             // jump if 80386 processor 

              push      ecx 

              popfd                     // restore AC bit in EFLAGS first 

     {$ENDIF} 

 

     // 486 processor check: 

     // Checking for ability to set/clear ID flag (Bit 21) in EFLAGS 

     // which indicates the presence of a processor with the CPUID instruction. 

              mov       [CPUType], 4    // turn on 80486 processor flag 

              mov       eax, ecx        // get original EFLAGS 

              xor       eax, 200000h    // flip ID bit in EFLAGS 

              push      eax             // save new EFLAGS value on stack 

              popfd                     // replace current EFLAGS value 

              pushfd                    // get new EFLAGS 

              pop       eax             // store new EFLAGS in EAX 

              xor       eax, ecx        // can't toggle ID bit, 

              je        @@2             // processor=80486 

 

     // higher than 486 check: 

     // Execute CPUID instruction to determine vendor, family, 

     // model, stepping and features. For the purpose of this 

     // code, only the initial (0) set of CPUID information is saved. 

              mov       [CPUIdFlag], 1  // flag indicating use of CPUID inst. 

              push      ebx             // save ebx register 

              mov       eax, 0          // set up for CPUID instruction 

              dw        CpuId           // Hardcoded CPUID instruction 

              mov       [MaxCPUId], eax // keep max value 

     // get and save vendor ID 

              mov       [byte ptr VendorId], 12 

              mov       [dword ptr VendorId+1], ebx 

              mov       [dword ptr VendorId+5], edx 

              mov       [dword ptr VendorId+9], ecx 

 

     // get family/model/stepping/features 

              call      ClearF 

              mov       eax, 1 

              call      GetF            // get feature stuff 

              shr       eax, 8          // isolate family 

              and       eax, 0fh 

              mov       [CPUType], al   // set CPUType with family 

     @@1:     pop       ebx             // restore ebx register 

     @@2

     end

 

     // requires that a call has been made to CpuId procedure to set flags correctly 

     procedure LoadFeatures (I : integer); 

     asm 

              call      ClearF 

              cmp       [CpuIdFlag], 0  // test if CPUId instruction valid 

              je        @@1 

              mov       eax, [I]        // test if argument in range 

              cmp       [MaxCpuId], eax 

              jl        @@1 

              call      GetF            // ok let's do it 

     @@1

     end

 

     initialization 

       CheckOutCPU; 

     end.