; =====================================================
; Get CPU information
;
; (C) A. Frolov, 1997
;
; E-mail: frolov@glas.apc.org
; WWW:    http://www.glasnet.ru/~frolov
;            or
;         http://www.dials.ccas.ru/frolov
; =====================================================
  .model small

CPU_ID MACRO
  db 0fh
  db 0a2h
ENDM

  .stack 100h
  .data
  
  public _vendor_id_msg
  public _cpu_model
  public _cpu_signature
  public _features_ecx
  public _features_edx
  public _features_ebx
  public _get_cpu_model

_vendor_id_msg db "............", 0dh, 0ah, "$"
_cpu_model     db 0
_cpu_signature dd 0
_features_ecx  dd 0
_features_edx  dd 0
_features_ebx  dd 0

  .code
; ============================================
; _get_cpu_model
; ============================================
  .8086

_get_cpu_model proc

  call cpu_8086
  cmp ax, 0
  jz try_80286

  mov _cpu_model, 0
  jmp end_of_detect

try_80286:

  call cpu_80286
  cmp ax, 0
  jz try_80386

  mov _cpu_model, 2
  jmp end_of_detect

try_80386:

  call cpu_80386
  cmp ax, 0
  jz try_80486

  mov _cpu_model, 3
  jmp end_of_detect

try_80486:

  call cpu_80486
  cmp ax, 0
  jz Pent_CPU

  mov _cpu_model, 4
  jmp end_of_detect

Pent_CPU:

  mov _cpu_model, 5

  .386
  pusha

  mov eax, 00h
  CPU_ID

  mov dword ptr _vendor_id_msg, ebx
  mov dword ptr _vendor_id_msg[+4], edx
  mov dword ptr _vendor_id_msg[+8], ecx

  cmp eax, 1
  jl end_of_detect
  
  mov eax, 1
  CPU_ID

  mov _cpu_signature, eax
  mov _features_ebx, ebx
  mov _features_edx, edx
  mov _features_ecx, ecx

  popa

end_of_detect:
  
  .8086
  ret

_get_cpu_model endp

; ============================================
; cpu_8086
; ============================================
cpu_8086 proc
  pushf
  pop ax
  mov cx, ax
  and ax, 0fffh
  push ax
  popf
  pushf
  pop ax
  and ax, 0f000h

  cmp ax, 0f000h
  je is_8086

  mov ax, 0
  ret

is_8086:
  mov ax, 1
  ret

cpu_8086 endp

; ============================================
; cpu_80286
; ============================================
  .286
cpu_80286 proc

  mov ax, 0f000h
  push ax
  popf
  pushf
  pop ax
  and ax, 0f000h
  jz is_80286

  mov ax, 0
  ret

is_80286:
  mov ax, 1
  ret

cpu_80286 endp

; ============================================
; cpu_80386
; ============================================
  .386
cpu_80386 proc
  pushfd
  pop eax
  mov ecx, eax
  xor eax, 40000h
  push eax
  popfd
  pushfd
  pop eax
  xor eax, ecx
  jz is_80386

  mov ax, 0
  ret

is_80386:
  push ecx
  popfd

  mov ax, 1
  ret

cpu_80386 endp

; ============================================
; cpu_80486
; ============================================
cpu_80486 proc
  pushfd
  pop eax
  mov ecx, eax

  xor eax, 200000h
  push eax
  popfd
  pushfd
  pop eax
  xor eax, ecx
  je is_80486

  mov ax, 0
  ret

is_80486:

  mov ax, 1
  ret

cpu_80486 endp

  end
