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