brender-1997/host/cpuid.asm
2022-05-03 14:31:40 -07:00

139 lines
3.9 KiB
NASM

;; Copyright (c) 1992,1993-1995 Argonaut Technologies Limited. All rights reserved.
;;
;; $Id: cpuid.asm 1.2 1998/08/17 16:15:44 johng Exp $
;; $Locker: $
;;
;; Inquiry to find processor type and features
;;
;; Based on Intel code
;;
.586
.model small,c
include host.inc
.code
CPUInfo proc uses ebx esi edi, cpu_type:ptr dword, features: ptr dword
; Assume 386 as worst case
;
mov esi,features
mov dword ptr [esi],0
mov esi,cpu_type
mov dword ptr [esi],BRT_INTEL_386
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
jz quit ; jump if 80386 processor
push ecx
popfd ; restore AC bit in EFLAGS first
; 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.
mov esi,cpu_type
mov dword ptr [esi],BRT_INTEL_486
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 quit ; processor=80486
; Execute CPUID instruction to determine vendor, family,
; model, stepping and features. For the purpose of this
; code, only the initial set of CPUID information is saved.
;
mov eax, 0 ; set up for CPUID instruction
cpuid
; get and save vendor ID
cmp eax, 1 ; make sure 1 is valid input for CPUID
jl quit
mov eax, 1
cpuid ; get family/model/stepping/features
shr eax, 8 ; isolate family
and eax, 0fh
cmp eax,6
jle known_cpu
mov eax,6 ; treat any future cpus as p-pros.
known_cpu:
lea ebx,cpu_types ; Convert to token
mov eax,[ebx+4*eax]
mov esi,cpu_type
mov [esi],eax
xor eax,eax
test edx,1
je no_fpu
or eax,HOST_CAPS_FPU
no_fpu:
test edx,(1 shl 23)
je no_mmx
or eax,HOST_CAPS_MMX
no_mmx:
test edx,(1 shl 15)
je no_cmov
or eax,HOST_CAPS_CMOV
no_cmov:
mov esi,features
mov [esi],eax
; check to see if the processor is a cyrix, mask out cmov if it is
; a small number of older cyrix processsors have a bug relating to their
; implementation of new floating point instructions indicated by cmov bit.
mov eax,00000000
cpuid ; cpuid w/eax=0, gets the VendorID
cmp ebx,069727943h ; "Cyri"
jnz NotCyrix
cmp edx,0736e4978h ; "xins"
jnz NotCyrix
cmp ecx,064616574h ; "tead"
jnz NotCyrix
mov eax,[esi]
and eax,NOT HOST_CAPS_CMOV ; clear CMOV bit
mov [esi],eax
NotCyrix:
quit: ret
CPUInfo endp
.data
cpu_types dword BRT_INTEL_386 ; 0
dword BRT_INTEL_386 ; 1
dword BRT_INTEL_386 ; 2
dword BRT_INTEL_386 ; 3
dword BRT_INTEL_486 ; 4
dword BRT_INTEL_PENTIUM ; 5
dword BRT_INTEL_PENTIUM_PRO ; 6
end