;
; GRDB
;
; Copyright(c) LADsoft
;
; David Lindauer, camille@bluegrass.net
;
;
; cpuid.asm
;
; Function: Generic CPU identification
;

	.model small
	.586
;cpuid	macro
;	db	0fh,0a2h
;endm

	public	checkcpu, cpumodel, cpufeatures

	.data
cpufeatures	dd	0	;holds features available
cpumodel	db	0	;model (3,4,5,6 etc.)

	.code
checkcpu	PROC
;
; 8086 has bits 12-15 of flags stuck on
;
	pushf
	pop	bx
	mov	ax,0fffh
	and	ax,bx
	push	ax
	popf
	pushf
	pop	ax
	and	ax,0f000h
	cmp	ax,0f000h
	jz	failed
;
; 80286 has bits 12-15 of flags stuck off
;
	mov	[cpumodel],2
	mov	ax,0f000h
	or	ax,bx
	push	ax
	popf
	pushf
	pop	ax
	and	ax,0f000h
	jz	failed
;
; Now we have a 386 or better.  On a 386 the AC bit (bit 18)
; may not be toggled
;
	mov	[cpumodel],3
	pushfd
	pop	eax
	cli
	mov	dx,sp
	and	sp,NOT 3
	mov	ebx,eax
	btc	eax,18
	push	eax
	popfd
	pushfd
	pop	eax
	push	ebx
	popfd
	mov	sp,dx
	xor	eax,ebx
	bt	eax,18
	jnc	gotid
;
; Now see if a is a pentium or better.  CPUID flag (bit 21) may not
; be toggled on a 486
	mov	[cpumodel],4
	mov	eax,ebx
	btc	eax,21
	push	eax
	popfd
	pushfd
	pop	eax
	xor	eax,ebx
	bt	eax,21
	jnc	gotid
	
;
; It is a pentium or better
;
; so issue a CPUID instruction (level 1) to get the model # and features dword
;
	push	ebx
	mov	eax,1
	cpuid
	mov	[cpufeatures],edx
	and	ah,15
	mov	[cpumodel],ah
	pop	ebx
gotid:
	push	ebx
	popfd
	clc
	ret
failed:
	push	bx
	popf
	stc
	ret
checkcpu	ENDP
	END