[comp.lang.pascal] Processor Detection

streich@boulder.Colorado.EDU (Mark Streich) (07/23/90)

Here is a slightly changed version of James Howard's (of Dell Computer Corp)
processor detection program.  It works in Turbo Pascal. (at least in 5.5,
which I was able to check)  As I only have a '386 immediately available,
could someone else report on how it works on the other processors.  It
did work with QEMM, by the way.

It should work with any other compiler which expects integer function
results to be returned in the AX register.

Instead of printing a message, as Howard's version did, this is a function
returning an integer that represents the type of processor on the machine.
============================================================================

Unit Detect;

Interface

Function DetectCPU : Integer;
{ Returns: 86 (8086/8), 186 (80186/8), 286 (80286), or 386 (80386) }

Implementation

Function DetectCPU : Integer; external;
{$L Detect}

end.

============================================================================
;
; CPU.ASM -- Determine CPU Type on any IBM or Compatible
;
; DESCRIPTION: Uses particular unique attributes of 8088/86, 80188/86,
;              80286, and 80386 Microprocessors to determine CPU type
;              during runtime.  This is useful to enable specialized
;              routines to take advantage of enhanced instructions if
;              available.
;
; Notes:
;
;   8088/86
;           This CPU has a unique way of handling the instruction PUSH SP,
;           which is commonly tested from software with three instructions.
;  80188/86
;           However, it does not help in determining the existence of a
;           80186/88 processor, because it is the same as the 80286 in the
;           way it handles PUSH SP.  Instead, there is a common difference
;           in that the flag register is handled differently.  If bits 12-15
;           are always held high, it is either an 808x or 8018x processor.
;           To decide which it is after this is tested, the way the SHL CX
;           instruction is handled can be used.  On an 808x, if CX > 32 it
;           will go ahead and shift it around anyway.  On an 80x8x, the high
;           order is masked off, so SHL CX with CX=35 will really only shift
;           3 (35-32).
;     80286
;           Once you know it is not a 808x, you need to determine if it is an
;           80286 or 80386 processor.  This again can be determined by looking
;           at the flags register. If bits 12-14 are forced low, it is a 286.
;     80386
;           If it falls through, it must be an 80386 by default.
;

code            segment byte public

assume          cs:code

DetectCPU       proc    far
                public  DetectCPU

                xor     ax,ax                   ; zero AX
                push    ax
                popf                            ; pop AX(=0) into flags
                pushf
                pop     ax                      ; pop AX
                and     ax,0f000h               ; see if bits tied high
                cmp     ax,0f000h               ; for 8088/186
                jz      is_0_1                  ; a 8018x or 808x

                mov     ax,07000h               ; see if 12-14 tied low
                push	ax
                popf
                pushf
                pop	ax
                and     ax,07000h               ; if 12-14 are 0
                jz      is_80286                ; then is 80286

is_80386:
                mov     ax,386                  ; else it's a 80386
                jmp     short return
is_80286:
                mov     ax,286                  ; it's a 80286
                jmp     short return
is_0_1:
                push	cx
                mov     ax,0ffffh               ; set to all ones
                mov     cl,33                   ; try to shift more than 32
                shl     ax,cl                   ; 808x will shift all bits out
                jnz     is_80186                ; nonzero bit means 8018x
is_8086:
                mov     ax,86
	        pop	cx
                jmp     short return
is_80186:
                mov     ax,186
                pop	cx

return:	        retf

DetectCPU       endp

code		ends
                end