winamp/Src/libvpShared/corelibs/CpuID/Win32/cpuid.asm

281 lines
7.3 KiB
NASM

;//==========================================================================
;//
;// 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