;//========================================================================== ;// ;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY ;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE ;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR ;// PURPOSE. ;// ;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved. ;// ;//-------------------------------------------------------------------------- ; ; **-getCPUType ; ; This function will return a code indicating the type of the processor ; that is in the system. If the processor type is unknown the generic ; x86 (Intel 486) type is returned ; ; parts taken from intel's AP-485 ; ;put checks for cmov and mmx support ???? ; ; Assumptions: ; None ; ; Input: ; None ; ; Output: ; Code for CPU type returned. See cpuidlib.h for the supported ; types. ; .586 .MODEL flat, SYSCALL, os_dos .DATA NAME x86cpuid PUBLIC getCPUType_ PUBLIC _getCPUType CPU_ID MACRO db 0fh ; Hardcoded CPUID instruction db 0a2h ENDM ;see cpuidlib.h X86 EQU 0 ; /* 486, Pentium plain, or any other x86 compatible */ PMMX EQU 1 ; /* Pentium with MMX */ PPRO EQU 2 ; /* Pentium Pro */ PII EQU 3 ; /* Pentium II */ C6X86 EQU 4 C6X86MX EQU 5 AMDK63D EQU 6 AMDK6 EQU 7 AMDK5 EQU 8 XMM EQU 11 WMT EQU 12 ;/* Willamette */ _486 EQU 4h PENT EQU 50h PENTMMX EQU 54h PENTPRO EQU 61h PENTII EQU 63h SIMD EQU 25 AMD_K63D EQU 58h AMD_K6 EQU 56h AMD_K5 EQU 50h ; K5 has models 0 - 6 _6X86 EQU 52h _6X86MX EQU 60h _vendor_id db "------------" intel_id db "GenuineIntel" amd_id db "AuthenticAMD" cyrix_id db "CyrixInstead" .CODE getCPUType_: _getCPUType: push esi ;safety sh*& push edi push ebp push ebx push ecx push edx ;------------------------------------------------ ; Intel486 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. ;------------------------------------------------ check_80486: pushfd ; push original EFLAGS pop eax ; get original EFLAGS mov ebp,X86 ; rv mov ecx, eax ; save 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 not toggle ID bit, je end_cpu_type486 ; processor=80486 ;------------------------------------------------ ; Execute CPUID instruction to not determine vendor, family, ; model, stepping and features. For the purpose of this ; code, only the initial set of CPUID information is saved. ;------------------------------------------------ ; push ebx ; save registers ; push esi ; push edi ; push edx ; push ecx ; mov ebp,X86 ; rv mov eax, 0 ; set up for CPUID instruction CPU_ID ; get and save vendor ID mov DWORD PTR _vendor_id, ebx mov DWORD PTR _vendor_id[+4], edx mov DWORD PTR _vendor_id[+8], ecx cmp DWORD PTR intel_id, ebx jne IsProc_AMD cmp DWORD PTR intel_id[+4], edx jne end_cpuid_type cmp DWORD PTR intel_id[+8], ecx jne end_cpuid_type ; if not equal, not an Intel processor cmp eax, 1 ; make sure 1 is valid input for CPUID jl end_cpuid_type ; if not, jump to end mov eax, 1 CPU_ID ; get family/model/stepping/features mov ebp,XMM ; assume PIII bt edx,SIMD ; check for SIMD support jnae end_cpuid_type SIMDContinue: shr eax, 4 ; isolate family and model mov ebp,PII ; assume PII and eax,0ffh ;mask out type and reserved nop cmp eax,PENTII jge end_cpuid_type mov ebp,PPRO cmp eax,PENTPRO je end_cpuid_type mov ebp,PMMX cmp eax,PENTMMX je end_cpuid_type mov ebp,X86 cmp eax,PENT jge end_cpuid_type ; mov ebp,X86 end_cpuid_type: mov eax,ebp ;remove these pops ??? ; pop edi ; restore registers ; pop esi ; pop ebx ; pop edx ; pop ecx end_cpu_type: pop edx ;safety sh*& pop ecx pop ebx pop ebp pop edi pop esi ret end_cpu_type486: mov eax,ebp pop edx ;safety sh*& pop ecx pop ebx pop ebp pop edi pop esi ret ;------------------------------------------------ IsProc_AMD: cmp DWORD PTR amd_id, ebx jne IsProc_CYRIX cmp DWORD PTR amd_id[+4], edx jne end_cpuid_type cmp DWORD PTR amd_id[+8], ecx jne end_cpuid_type ; if not equal, not an AMD processor cmp eax, 1 ; make sure 1 is valid input for CPUID jl end_cpuid_type ; if not, jump to end mov eax, 1 CPU_ID ; get family/model/stepping/features shr eax, 4 ; isolate family and model mov ebp,AMDK63D and eax,0ffh ;mask out type and reserved nop cmp eax,AMD_K63D jge end_cpuid_type mov ebp,AMDK6 nop cmp eax,AMD_K6 jge end_cpuid_type mov ebp,X86 nop cmp eax,AMD_K5 jge end_cpuid_type mov ebp,X86 jmp end_cpuid_type ;------------------------------------------------ IsProc_CYRIX: cmp DWORD PTR cyrix_id, ebx jne end_cpuid_type cmp DWORD PTR cyrix_id[+4], edx jne end_cpuid_type cmp DWORD PTR cyrix_id[+8], ecx jne end_cpuid_type ; if not equal, not an CYRIX processor cmp eax, 1 ; make sure 1 is valid input for CPUID jl end_cpuid_type ; if not, jump to end mov eax, 1 CPU_ID ; get family/model/stepping/features shr eax, 4 ; isolate family and model mov ebp,C6X86MX and eax,0ffh ;mask out type and reserved nop cmp eax,_6X86MX je end_cpuid_type mov ebp,X86 jmp end_cpuid_type ;************************************************ END