; Project:  	Workstation inventory
; File:		CPUTYPE.ASM
; Author:	used by permission of Intel Corporation.
; Date:		12/15/91
;
; Returns:      AX = CPU type 
;            0086H = 8086 or 8088
;            0286H = 80286
;            0386H = 80386SX or 80386DX
;            0486H = 80486SX or 80486DX
;
; Destroys:     upper 16-bits of EAX and ECX on 386/486

.386

_TEXT   segment word use16 public 'CODE'

        assume  cs:_TEXT

        public  _cputype
_cputype proc    near

        pushf                           ; save flags
        push    bx                      ; save registers used
        push    cx
        pushf                           ; try to clear bits 12-15 of flags
        pop     ax
        and     ax,0fffh
        push    ax                      ; set modified flags
        popf
        pushf
        pop     ax                      ; get flags again
        and     ax,0f000h               ; if bits 12-15 are still       
        cmp     ax,0f000h               ; set, this is 8086/88
        jne     cpu1                    ; jump, not 8086/88
        mov     ax,0086h                ; set AX = 86/88 CPU type
        jmp     cpux                    ; and exit

cpu1:   or      ax,0f000h               ; must be 286 or later, 
        push    ax                      ; now try to set bits 12-15
        popf                            ; of CPU flags
        pushf
        pop     ax                      ; if bits 12-15 can't be
        and     ax,0f000h               ; set, this is a 286
        jnz     cpu2                    ; jump, not 80286
        mov     ax,286h                 ; set AX = 286 CPU type
        jmp     cpux                    ; and exit

cpu2:   mov     bx,sp                   ; 386 or later, save SP
        and     sp,not 3                ; avoid stack alignment fault
        pushfd                          ; get value of EFLAGS
        pop     eax
        mov     ecx,eax                 ; save copy of EFLAGS 
        xor     eax,40000h              ; flip AC bit in EFLAGS
        push    eax                     ; try and force EFLAGS
        popfd
        pushfd                          ; get back EFLAGS value
        pop     eax
        mov     sp,bx                   ; restore old stack pointer
        xor     eax,ecx                 ; can AC bit be changed?
        jnz     cpu3                    ; no, jump, not a 386
        mov     ax,0386h                ; set AX = 386 CPU type
        jmp     cpux                    ; and exit

cpu3:   mov     ax,0486h                ; set AX = 486 CPU type 

cpux:   pop     cx                      ; restore registers
        pop     bx
        popf                            ; restore original flags
        ret                             ; return with AX = cpu type

_cputype endp

_TEXT   ends

        end     

