Subversion Repositories decoder

Rev

Blame | Last modification | View Log | RSS feed

  1. {Copyright:      Hagen Reddmann  HaReddmann at T-Online dot de
  2.  Author:         Hagen Reddmann
  3.  Remarks:        Public Domain, this Copyright must be included
  4.  known Problems: none
  5.  Version:        5.1, Delphi Encryption Compendium
  6.                  Delphi 2-7, BCB 3-4, designed and testet under D3-7
  7.  Description:    CPU Detection, single Unit
  8.  Remarks:
  9.    - codesizes       503 (CPUType)
  10.                     1003 (CPUType, CPUSpeed)
  11.                     5035 (CPUType, CPUSpeed, CPUVendor) bytes
  12.    - datasize (BSS)  142 bytes
  13.    - datasize (DATA) 100 bytes if CPUVendor is used
  14.        minimal       645 bytes in EXE
  15. }
  16.  
  17. unit CPU;
  18.  
  19. interface
  20.  
  21. type
  22. {CPU Detection}
  23.   TCPUData = packed record
  24.     Typ: Byte;
  25.     Family: Byte;
  26.     Model: Byte;
  27.     Stepping: Byte;
  28.     Signature: Cardinal;            // encoded Typ/Family/Model/Stepping
  29.     Features_EDX: Cardinal;         // Features
  30.     Features_EBX: Cardinal;
  31.     Features_ECX: Cardinal;
  32.     FeaturesEx_EDX: Cardinal;       // extended Features AMD/Cyrix
  33.     FeaturesEx_EBX: Cardinal;
  34.     FeaturesEx_ECX: Cardinal;
  35.     Vendor: array[0..12] of Char;   // inculdes trailing #0
  36.     VendorEx: array[0..64] of Char; //    "         "
  37.     CPUID3: array[0..4] of Cardinal;
  38.     VendorID: Cardinal;
  39.     TLB_EAX: Cardinal;              // Cache and TLB Infos, see Intel Docus
  40.     TLB_EDX: Cardinal;
  41.     TLB_EBX: Cardinal;
  42.     TLB_ECX: Cardinal;
  43.   end;
  44.  
  45. const
  46. // CPU Family codes
  47.   cf386        = 3;
  48.   cf486        = 4;
  49.   cfPentium    = 5;
  50.   cfPentiumPro = 6;
  51. // CPU Types
  52.   ctOEM        = 0;
  53.   ctOverdrive  = 1;
  54.   ctDual       = 2;
  55. // Vendor codes
  56.   cvIntel      = $506E7F40; // CRC('GenuineIntel'); Intel
  57.   cvAMD        = $454D5A47; // CRC('AuthenticAMD'); AMD
  58.   cvCyrix      = $7E7D554F; // CRC('CyrixInstead'); Cyrix
  59.   cvUMC        = $20434D55; // CRC('UMC UMC UMC '); UMC
  60.   cvNexGen     = $5B597D42; // CRC('NexGenDriven'); NexGen
  61.   cvCentaur    = $4F706543; // CRC('CentaurHauls'); Centaur/IDT
  62.   cvRise       = $65736952; // CRC('RiseRiseRise'); Rise Technology
  63.   cvTransmeta  = $17337363; // CRC('GenuineTMx86'); Transmeta
  64.  
  65. // CPU Features
  66.   ffFPU        = $00000001; // Floating Point Unit on Chip
  67.   ffVME        = $00000002; // Virtual 8086 Mode Enhancements
  68.   ffDE         = $00000004; // Debugging Extensions
  69.   ffPSE        = $00000008; // Page Size Extensions
  70.   ffTSC        = $00000010; // Time Stamp Counter, supports RDTSC Instruction
  71.   ffMSR        = $00000020; // Model Specific Registers, supports RDMSR Instruction
  72.   ffPAE        = $00000040; // Physical Address Extension
  73.   ffMCE        = $00000080; // Machine Check Exception
  74.   ffCX8        = $00000100; // CMPXCHG Instruction supported
  75.   ffAPIC       = $00000200; // Advanced Programmable Interrupt Controller
  76. // ffRes1               = $00000400;
  77.   ffSEP        = $00000800; // Fast System Call, SYSENTER and SYSEXIT Instruction
  78.   ffMTRR       = $00001000; // Memory Type Range Registers
  79.   ffPGE        = $00002000; // Global Flag Processor supported
  80.   ffMCA        = $00004000; // Machine Check Architecture
  81.   ffCMOV       = $00008000; // CMOV/FCOMI Instructions supported
  82.   ffFGPAT      = $00010000; // Page Attribute Table, CMOVcc supported
  83.   ffPSE36      = $00020000; // PSE-36—36-bit Page Size Extension
  84.   ffPN         = $00040000; // PN—Processor Number, supports the 96-bit PN feature
  85.   ffCLFSH      = $00080000; // CLFLUSH intsturction supported
  86. // ffRes2               = $00100000;
  87.   ffDS         = $00200000; // Debug Store supported
  88.   ffACPI       = $00400000; // Thermal Monitor and Software Controlled Clock Features
  89.   ffMMX        = $00800000; // MMX instruction set
  90.   ffFXSR       = $01000000; // Fast FP/MMX™ Technology/Streaming SIMD Extensions
  91.   ffSSE        = $02000000; // Streaming SIMD Extensions Instruction set
  92.   ffSSE2       = $04000000; // Streaming SIMD Extensions Instruction set 2
  93.   ffSS         = $08000000; // Self-Snoop supported
  94.   ffHTT        = $10000000; // Hyper-Threading Technology
  95.   ffTM         = $20000000; // Thermal control circuit TCC supported
  96.   ffIA64       = $40000000; // IA-64 architecture
  97. // ffRes5               = $80000000;
  98.                
  99. function CPUType: Integer; {any cfXXXX Value}
  100. function CPUData: TCPUData;
  101. function CPUVendor: String;
  102. function CPUSpeedRaw(Delay: Cardinal): Comp;
  103. function CPUSpeed: Cardinal;
  104.  
  105. function PerfCounter: Comp;
  106. function PerfFreq: Comp;
  107. function RDTSC: Int64;
  108.  
  109. implementation
  110.  
  111. uses Windows, SysUtils;
  112.  
  113. resourcestring
  114.   sCPU_Unknown         = '%s P%d Model %d';
  115.   sCPU_Dual            = ' (Dual Processor)';
  116.   sCPU_Model           = ' Model ';
  117.   sCPU_Compatible      = ' (compatible)';
  118.  
  119. var
  120.   FCPU: TCPUData;
  121.  
  122. function QPC(var C: Comp): Bool; stdcall; external 'kernel32.dll' name 'QueryPerformanceCounter';
  123. function QPF(var F: Comp): Bool; stdcall; external 'kernel32.dll' name 'QueryPerformanceFrequency';
  124.  
  125. function PerfCounter: Comp;
  126. begin
  127.   if not QPC(Result) then Result := GetTickCount
  128. end;
  129.  
  130. function PerfFreq: Comp;
  131. begin
  132.   if not QPF(Result) then Result := 1000
  133. end;
  134.  
  135. function RDTSC: Int64;
  136. asm
  137.      DW    0310Fh
  138. end;
  139.  
  140. {CPU Routines}
  141. function CPUType: Integer;
  142. begin
  143.   Result := FCPU.Family;
  144. end;
  145.  
  146. function CPUSpeedRaw(Delay: Cardinal): Comp;
  147. var
  148.   C: Comp;
  149.   D: Double;
  150. begin
  151.   Result := 0;
  152.   if FCPU.Features_EDX and ffTSC <> 0 then
  153.   try // except Block needed, RDTSC can be a privilege Instruction !! but should never
  154.     if Delay <= 0 then Delay := 10;
  155.     D := PerfCounter;              // API QueryPerformanceCounter() based on a virtual 1.19318 MHz CPU
  156.     asm
  157.        PUSHAD
  158.        DW     0310Fh               // RDTSC, read Time Stamp Counter into C
  159.        MOV    C.DWord[0],EAX       // RDTSC is an CPU Clock based value
  160.        MOV    C.DWord[4],EDX       // incremented on ONE CPU Clock.
  161.        POPAD
  162.     end;
  163.     Inc(Delay, GetTickCount);
  164.     while GetTickCount < Delay do ;
  165.     asm
  166.        PUSHAD
  167.        DW     0310Fh               // C := RDTSC - C
  168.        SUB    EAX,C.DWord[0]
  169.        SBB    EDX,C.DWord[4]
  170.        ADD    EAX,5000             // subtract ~Cycles of follow API call
  171.        ADC    EDX,0
  172.        MOV    C.DWord[0],EAX
  173.        MOV    C.DWord[4],EDX
  174.        POPAD
  175.     end;
  176.     D := PerfCounter - D;          
  177.     Result := C * PerfFreq / D;
  178.   except
  179.   end;
  180. end;
  181.  
  182. function CPUSpeed: Cardinal;
  183. // returns corrected speed
  184. {$J+}
  185. const
  186.   FSpeed: Cardinal = 0;
  187. {$J-}
  188.    FS1: array[0..47] of Word = (
  189.       0,   25,   33,   60,   66,   75,   82,   90,
  190.     100,  110,  116,  120,  133,  150,  166,  180,
  191.     188,  200,  225,  233,  266,  300,  333,  350,
  192.     366,  400,  415,  433,  450,  466,  500,  533,
  193.     550,  600,  650,  667,  700,  733,  750,  800,
  194.     833,  850,  866,  900,  933,  950,  966, 1000);
  195.   FS2: array[0..5] of Byte = (
  196.       0,   33,   50,   66,  100,  133);
  197. var
  198.   I,S: Integer;
  199. begin
  200.   if FSpeed = 0 then
  201.   begin
  202.     S := Round(CPUSpeedRaw(10) / 1000000);
  203.     for I := Low(FS1) +1 to High(FS1) -1 do
  204.       if (S = FS1[I]) or
  205.          ((S >= FS1[I] - (FS1[I] - FS1[I -1]) div 2) and
  206.           (S <  FS1[I] + (FS1[I +1] - FS1[I]) div 2)) then
  207.       begin
  208.         FSpeed := FS1[I];
  209.         Break;
  210.       end;
  211.     if FSpeed = 0 then
  212.     begin
  213.       FSpeed := S;
  214.       S := S mod 100;
  215.       Dec(FSpeed, S);
  216.       for I := Low(FS2) +1 to High(FS2) -1 do
  217.         if (S = FS2[I]) or
  218.            ((S >= FS2[I] - (FS2[I] - FS2[I -1]) div 2) and
  219.             (S <  FS2[I] + (FS2[I +1] - FS2[I]) div 2)) then
  220.         begin
  221.           Inc(FSpeed, FS2[I]);
  222.           Break;
  223.         end;
  224.     end;
  225.   end;
  226.   Result := FSpeed;
  227. end;
  228.  
  229. function CPUData: TCPUData;
  230. begin
  231.   Result := FCPU;
  232. end;
  233.  
  234. {check is CPUID Instruction present}
  235. function CPUID_Found: LongBool; assembler;
  236. asm
  237.        PUSHFD
  238.        PUSHFD
  239.        POP     EAX
  240.        MOV     EDX,EAX
  241.        XOR     EAX,0040000h
  242.        PUSH    EAX
  243.        POPFD
  244.        PUSHFD
  245.        POP     EAX
  246.        XOR     EAX,EDX
  247.        JZ      @@1
  248.        PUSHFD
  249.        POP     EAX
  250.        MOV     EDX,EAX
  251.        XOR     EAX,0200000h
  252.        PUSH    EAX
  253.        POPFD
  254.        PUSHFD
  255.        POP     EAX
  256.        XOR     EAX,EDX
  257. @@1:   POPFD
  258. end;
  259.  
  260. {initialize the CPU Datastruct}
  261. procedure GetCPU;
  262.  
  263.   function CRC(const Value): Cardinal; assembler;
  264.   asm
  265.       MOV  EDX,EAX
  266.       MOV  EAX,[EDX + 0]
  267.       XOR  EAX,[EDX + 4]
  268.       XOR  EAX,[EDX + 8]
  269.   end;
  270.  
  271. var
  272.   ID: Word;
  273. begin
  274.   FillChar(FCPU, SizeOf(FCPU), 0);
  275.   if CPUID_Found then
  276.   asm
  277.        PUSH    EDI
  278.        PUSH    EBX
  279.  
  280.        MOV     EDI,OFFSET FCPU
  281.        LEA     EDI,[EDI].TCPUData.Vendor
  282.        XOR     EAX,EAX
  283.        DW      0A20Fh             //     CPUID
  284.        MOV     [EDI + 0],EBX
  285.        MOV     [EDI + 4],EDX
  286.        MOV     [EDI + 8],ECX
  287.  
  288.        MOV     EDI,OFFSET FCPU
  289.        CMP     EAX,2
  290.        JL      @@1
  291.        MOV     EAX,2
  292.        DW      0A20Fh
  293.        MOV     [EDI].TCPUData.TLB_EAX,EAX
  294.        MOV     [EDI].TCPUData.TLB_EDX,EDX
  295.        MOV     [EDI].TCPUData.TLB_EBX,EBX
  296.        MOV     [EDI].TCPUData.TLB_ECX,ECX
  297. @@1:   MOV     EAX,1
  298.        XOR     EBX,EBX
  299.        XOR     ECX,ECX
  300.        DW      0A20Fh
  301.        MOV     [EDI].TCPUData.Signature,EAX
  302.        MOV     DWord Ptr [EDI].TCPUData.CPUID3[0],EAX
  303.        MOV     [EDI].TCPUData.Features_EDX,EDX
  304.        MOV     [EDI].TCPUData.Features_EBX,EBX
  305.        MOV     [EDI].TCPUData.Features_ECX,ECX
  306.  
  307.        MOV     EDX,EAX
  308.        AND     EAX,0Fh
  309.        MOV     [EDI].TCPUData.Stepping,AL
  310.        SHR     EDX,4
  311.        MOV     EAX,EDX
  312.        AND     EAX,0Fh
  313.        MOV     [EDI].TCPUData.Model,AL
  314.        SHR     EDX,4
  315.        MOV     EAX,EDX
  316.        AND     EAX,0Fh
  317.        MOV     [EDI].TCPUData.Family,AL
  318.        SHR     EDX,4
  319.        AND     EDX,0Fh
  320.        MOV     [EDI].TCPUData.Typ,DL
  321.  
  322.        MOV     EAX,080000000h
  323.        XOR     EDX,EDX
  324.        XOR     EAX,EAX
  325.        DW      0A20Fh
  326.        TEST    EAX,EAX
  327.        JLE     @@3
  328.        AND     EDX,EDX
  329.        JZ      @@3
  330.        PUSH    EAX
  331.        MOV     EAX,080000001h
  332.        DW      0A20Fh
  333.        MOV     [EDI].TCPUData.FeaturesEx_EDX,EDX
  334.        MOV     [EDI].TCPUData.FeaturesEx_EBX,EBX
  335.        MOV     [EDI].TCPUData.FeaturesEx_ECX,ECX
  336.        POP     EAX
  337.        CMP     EAX,1
  338.        JBE     @@3
  339.        PUSH    ESI
  340.        PUSH    EDI
  341.        XOR     ESI,ESI
  342.        LEA     EDI,[EDI].TCPUData.VendorEx
  343. @@2:   LEA     EAX,[080000002h + ESI]
  344.        XOR     EDX,EDX
  345.        XOR     EBX,EBX
  346.        XOR     ECX,ECX
  347.        DW      0A20Fh
  348.        MOV     [EDI +  0],EAX
  349.        MOV     [EDI +  4],EBX
  350.        MOV     [EDI +  8],ECX
  351.        MOV     [EDI + 12],EDX
  352.        INC     ESI
  353.        ADD     EDI,16
  354.        AND     ESI,3
  355.        JNZ     @@2
  356.        POP     EDI
  357.        POP     ESI
  358.  
  359. @@3:   XOR     EDX,EDX
  360.        XOR     ECX,ECX
  361.        XOR     EBX,EBX
  362.        MOV     EAX,3
  363.        DW      0A20Fh
  364.        MOV     DWord Ptr [EDI].TCPUData.CPUID3[ 4],EDX
  365.        MOV     DWord Ptr [EDI].TCPUData.CPUID3[ 8],ECX
  366.        MOV     DWord Ptr [EDI].TCPUData.CPUID3[12],EBX
  367.        MOV     DWord Ptr [EDI].TCPUData.CPUID3[16],EAX
  368.        POP     EBX
  369.        POP     EDI
  370.   end else
  371.   try
  372.     FCPU.Family := cf386;
  373.     asm
  374.        XADD    EAX,EAX
  375.        BSWAP   EAX
  376.  
  377.        PUSH    EDI
  378.        MOV     EDI,OFFSET FCPU
  379.        MOV     [EDI].TCPUData.Family,cf486
  380.        MOV     EAX,CR0
  381.        AND     EAX,not 010h
  382.        MOV     CR0,EAX
  383.        MOV     EAX,CR0
  384.        AND     EAX,    010h
  385.        JZ      @@1
  386.        INC     [EDI].TCPUData.Model
  387.        OR      ID,1
  388.        FNINIT
  389.        FNSTSW  ID
  390.        CMP     ID[0],0
  391.        JNE     @@1
  392.        FNSTCW  ID
  393.        MOV     AX,ID
  394.        AND     AX,013Fh
  395.        CMP     AX,003Fh
  396.        JNE     @@1
  397.        INC     [EDI].TCPUData.Model
  398. @@1:   POP     EDI
  399.     end;
  400.   except
  401.   end;
  402.   FCPU.VendorID := CRC(FCPU.Vendor);
  403. end;
  404.  
  405. function CPUVendor: String;
  406.  
  407.   function L2Cache: Cardinal;
  408.   begin // find L2 Cache definition
  409.     Result := FCPU.TLB_EDX;
  410.     while (Result and $40 = 0) and (Result <> 0) do Result := Result shr 8;
  411.     Result := Result and $FF;
  412.   end;
  413.  
  414. label
  415.   Unknown, Skip;
  416. var
  417.   Compatible: Boolean;
  418. begin
  419.   Compatible := False;
  420.   with FCPU do
  421.   begin
  422.     case VendorID of
  423.  // Intel ----------------------------
  424.       cvIntel:
  425.         begin
  426.           Result := 'Intel ';
  427. // use goto's, yes, not realy good coding style, but I want a compact solution
  428.           goto Skip;
  429. Unknown:
  430.           Compatible := True;
  431. Skip:
  432.           case Family of
  433.             cf386: Result := Result + '386';
  434.             cf486:
  435.               case Model of
  436. // on the way a small remark:
  437. // we use here concacted stringconstant,
  438. // compiler save optimated only once on different version into code,
  439. // and so we reduce the codesize.
  440.                 0: Result := Result + '486' + 'DX' + '25/30';
  441.                 1: Result := Result + '486' + 'DX' + '50';
  442.                 2: Result := Result + '486' + 'SX';
  443.                 3: Result := Result + '486' + 'DX' + '2';
  444.                 4: Result := Result + '486' + 'SL';
  445.                 5: Result := Result + '486' + 'SX' + '2';
  446.                 7: Result := Result + '486' + 'DX' + '2' + ' WB enhanced';
  447.                 8: Result := Result + '486' + 'DX' + '4';
  448.                 9: Result := Result + '486' + 'DX' + '4' + ' WB enhanced';
  449.               else
  450.                 Result := Result + '486' + sCPU_Model + IntToStr(Model);
  451.               end;
  452.             cfPentium:
  453.               case Model of
  454.                 0: Result := Result + 'Pentium' + ' P5' + ' A-step';
  455.                 1: Result := Result + 'Pentium' + ' P5';
  456.                 2: Result := Result + 'Pentium' + ' P5' + '4C';
  457.                 3: Result := Result + 'Pentium' + ' P5' + '4T' + ' ' + 'overdrive';
  458.                 4: Result := Result + 'Pentium' + ' P5' + '5C';
  459.                 7: Result := Result + 'Pentium' + ' P5' + '4C';
  460.                 8: Result := Result + 'Pentium' + ' P5' + '5C' + ' (0.25 µm)';
  461.               else
  462.                 Result := Result + 'Pentium' + sCPU_Model + IntToStr(Model);
  463.               end;
  464.             cfPentiumPro:
  465.               case Model of
  466.                 0: Result := Result + 'Pentium' + ' Pro (P6)' + ' A-step';
  467.                 1: Result := Result + 'Pentium' + ' Pro (P6)';
  468.                 3: Result := Result + 'Pentium' + ' II' + ' (0.28 µm)';
  469.                 5: begin
  470.                      Result := Result + 'Pentium' + ' II' + ' (0.25 µm)';
  471.                      case L2Cache of
  472.                        0: Result := Result + ' Celeron';
  473.                  $44,$45: Result := Result + ' Xenon';
  474.                      end;
  475.                    end;
  476.                 6: Result := Result + 'Pentium' + ' II' + ' L2 Cache';
  477.               7,8: begin
  478.                      Result := Result + 'Pentium';
  479.                      case Features_EBX and $FF of
  480.                        1: Result := Result + ' Celeron';
  481.                        3: Result := Result + ' III' + ' Xenon';
  482.                        8: Result := Result + ' IV'; // ? I don't known realy
  483.                      else
  484.                        begin
  485.                          Result := Result + ' III';
  486.                          if L2Cache in [$44,$45] then Result := Result + ' Xenon';
  487.                        end;
  488.                      end;
  489.                      if Model = 7 then Result := Result + ' (0.25 µm)'
  490.                        else Result := Result + ' (0.18 µm)';
  491.                    end;
  492.                10: Result := Result + 'Pentium' + ' III' + ' Xenon';
  493.               else
  494.                 Result := Result + 'Pentium' + ' II' + sCPU_Model + IntToStr(Model);
  495.               end;
  496.           else
  497.             Result := Format(sCPU_Unknown, [Vendor, Family, Model]);;
  498.           end;
  499.         end;
  500. // AMD ----------------------------
  501.       cvAMD:
  502.         begin
  503.           Result := 'AMD ';
  504.           case Family of
  505.             cf486:
  506.               case Model of
  507.                 14: Result := Result + '586';
  508.                 15: Result := Result + '586' + ' WB enhanced';
  509.               else
  510.                 goto Unknown;
  511.               end;
  512.             cfPentium:
  513.               case Model of
  514.                 0: Result := Result + 'K5' + ' SSA5' + ' (PR75, PR90, PR100)';
  515.                 1: Result := Result + 'K5' + ' 5k86' + ' (PR120, PR133)';
  516.                 2: Result := Result + 'K5' + ' 5k86' + ' (PR166)';
  517.                 3: Result := Result + 'K5' + ' 5k86' + ' (PR200)';
  518.                 6: Result := Result + 'K6' + ' (0.30 µm)';
  519.                 7: Result := Result + 'K6' + ' (0.25 µm)';
  520.                 8: Result := Result + 'K6' + ' II';
  521.                 9: Result := Result + 'K6' + ' III';
  522.                13: Result := Result + 'K6' + ' II+ or III+';
  523.               else
  524.                 goto Unknown;
  525.               end;
  526.             cfPentiumPro:
  527.               case Model of
  528.                 1: Result := Result + 'K7' + ' Athlon' + ' (0.25 µm)';
  529.                 2: Result := Result + 'K7' + ' Athlon' + ' (0.18 µm)';
  530.               3,4: Result := Result + 'K7' + ' Athlon';
  531.               else
  532.                 goto Unknown;
  533.               end;
  534.           else
  535.             goto Unknown;
  536.           end;
  537.         end;
  538. // Cyrix ----------------------------
  539.       cvCyrix:
  540.         begin
  541.           Result := 'Cyrix ';
  542.           case Family of
  543.             cf486:
  544.               case Model of
  545.                 4: Result := Result + '586' + ' Media GX';
  546.                 9: Result := Result + '586'
  547.               else
  548.                 goto Unknown;
  549.               end;
  550.             cfPentium:
  551.               case Model of
  552.                 2: Result := Result + 'M1' + ' 6x86';
  553.                 4: Result := Result + 'GXm';
  554.               else
  555.                 goto Unknown;
  556.               end;  
  557.             cfPentiumPro:
  558.               case Model of
  559.                 0: Result := Result + 'M2' + ' 6x86' + 'MX';
  560.                 5: Result := Result + 'M2' + ' VIA III';
  561.               else
  562.                 goto Unknown;
  563.               end;  
  564.           else
  565.             goto Unknown;
  566.           end;
  567.         end;
  568. // UMC ----------------------------
  569.       cvUMC:
  570.         begin
  571.           Result := 'UMC ';
  572.           if Family = cf486 then
  573.             case Model of
  574.               1: Result := Result + 'U5D';
  575.               2: Result := Result + 'U5S';
  576.             else
  577.               goto Unknown;
  578.             end
  579.           else goto Unknown;
  580.         end;
  581. // NexGen ----------------------------
  582.       cvNexGen:
  583.         begin
  584.           Result := 'NexGen ';
  585.           if (Family = cfPentium) and (Model = 0) then Result := Result + '586'
  586.             else goto Unknown;
  587.         end;
  588. // Centaur/IDT ----------------------------
  589.       cvCentaur:
  590.         begin
  591.           Result := 'Centaur/IDT ';
  592.           if Family = cfPentium then
  593.             case Model of
  594.               4: Result := Result + 'C6';
  595.               8: Result := Result + 'C2';
  596.               9: Result := Result + 'C3';
  597.             else
  598.               goto Unknown;
  599.             end
  600.           else goto Unknown;
  601.         end;
  602. // Rise Technology ----------------------------
  603.       cvRise:
  604.         begin
  605.           Result := 'Rise Technology ';
  606.           if Family = cfPentium then
  607.             case Model of
  608.               0: Result := Result + 'mP6' + ' (0.25 µm)';
  609.               2: Result := Result + 'mP6' + ' (0.18 µm)';
  610.             else
  611.               goto Unknown;
  612.             end
  613.           else goto Unknown;
  614.         end;
  615.     else
  616.       goto Unknown;
  617.     end;
  618.     if (Features_EDX and ffMMX <> 0) and (Pos('MMX', Result) = 0) then
  619.       Result := Result + ' ' + 'MMX';
  620.     if (Typ = ctOverdrive) and (Pos('overdrive', Result) = 0) then
  621.       Result := Result + ' ' + 'overdrive';
  622.     if (Typ = ctDual) and (Pos(sCPU_Dual, Result) = 0) then
  623.       Result := Result + sCPU_Dual;
  624.     if Compatible then
  625.       Result := Result + sCPU_Compatible;
  626.     if VendorEx[0] <> #0 then
  627.       Result := Result + ' "' + Trim(StrPas(VendorEx)) + '"';
  628.   end;
  629. end;
  630.  
  631.  
  632. initialization
  633.   GetCPU;
  634. end.
  635.