[net.micro.pc] How can I detect a '386?

marcl@3comvax.UUCP (Marc Lavine) (09/20/86)

I want a certain program to be able to distinguish between an 80386
and an 80286.  I could try using self-modifying code (to test the size
of the prefetch queue, but I was wondering if there might be simpler
methods.  This test will be done on a system running MS-DOS, so I
guess that means the '386 will be in real mode.  Any help would be
appreciated.
-- 
Marc Lavine
uucp:		...{ ihnp4 | hplabs | glacier }!oliveb!3comvax!marcl

clif@intelca.UUCP (Clif Purkiser) (09/23/86)

> I want a certain program to be able to distinguish between an 80386
> and an 80286.  I could try using self-modifying code (to test the size
> of the prefetch queue, but I was wondering if there might be simpler
> methods.  This test will be done on a system running MS-DOS, so I
> guess that means the '386 will be in real mode.  Any help would be
> appreciated.
> -- 
> Marc Lavine
> uucp:		...{ ihnp4 | hplabs | glacier }!oliveb!3comvax!marcl

Sorry to post this to the net.  But I got a message from the mail
deamon.   Hopefully it will be useful to the network.

The follow article is from a technical note I wrote on identifying
Intel microprocessors.  Note this test only works in Real Mode.  


                   IDENTIFYING INTEL MICROPROCESSORS

	Many companies will soon have systems based on three generations
of Intel microprocessor (8086/88, 80286, and the 80386.)   It is often
important that the same software be able to run on all three types of
computers.  Rather than writting all of the software to use only the
8086 instructions, many independent software vendors (ISVs) and
computer companies are writting software to take advantage of the new
features of the 80286 and/or 80386.

	The general method for doing this is to test what type of
processor the computer contains and then  branch to processor specific
routines.   This approach enables the same software to run on any
Intel processor while still allowing the greater addressing
capabilities and new instructions of the 80286/80386 to be used.

	There are several different methods of determining in software
the processor type.  One approach is to try the new instructions
available on each processor and see if they cause an illegal opcode
exception.  The only disadvantage with this approach is that it
requires access to the illegal opcode interrupt handler (exception 6)
in order to determine the processor type.

	 The April 86 issue of PC Tech contains an article by Bob Smith
which documents most of the non-transparent differences between the
8088, 8086, 80186, and 80286.  Mr. Smith's article seems to be
accurate but many of his methods for determining the processor type
seem to be unnecessarily complicated.

	More importantly Intel can not commit to support all of his tests
in future 8086 core proliforation products since many of his tests use
old errata.  Luckily a much simpler method of determining the 
processors type exists.

	My test for determining between 8086, 80286, and 80386 involves
taking advantage of differences in the flag register between the
processors.   Future versions of this processors will retain the same
flag settings.  

	Differentiating the 8086 from the 80286-80386

	Bit 15 of the flag register is undefined on all three
processors.  In fact the bit is a 1 on the 8086/88 and 80186/88 and a
0 on the 80286 and 80386.

	Differentiating the 80286 from 80386 

	Bit 14 of the flag register on the 80286 and the 80386 is the
Nested Task Flag.  Bits 12-13 of the flag register is the I/O
privilege level (IOPL).  Since these bits are only used for Protected
Mode software their values are undefined in Real Mode.

	In reality the bits are 0 after reset.  None of these bits can be
set on a 80286 in Real Mode.  On a 386 all three of these bits can be
set in Real Mode (although they have no effect).

	Differentiating the 8086 from the 80186	
	
	Unlike the other processors the 8086 and 80186 have no
differences in the settings of the flag bits.  However there is a
difference between the processors in the operation of the shift
instructions.  The shift by a count instruciton on the 8086 used all 8
bits in the CL register to shift by.  On the 80186 only the lower 5
bits are used as a count to the shift instruction.  Thus 80186/286/386
use CL MOD 32 for the shift count.  

	Therefore a shift of 33 is the same as a shift by 1 for the
80186/286/386 and on the 8086/88 it causes an all zero result.

	Future processors.  
	
	The 80386 contains a processor type and a stepping identifier in
the general purpose registers immediately after reset.  Initialization
software is strongly encouraged to check this registers and store the
processor type in an area available to application programs.  

	The 486 and future versions of the 386 will also contain this
stepping identifier.


	Identifying Intel Processors.

	The attached code sequence returns the processor type in the AX
register.  It should be distributed to any customers and Independent
Software vendors who could use it.

proc_type		proc		near
;
;	Returns the processor type in the AX 
;

	pushf				; Save FLAG registers
	xor		ax,ax		; Clear AX and push onto the stack.
	push		ax
	popf					;  Pop a zero into FLAGs register
	pushf				;  Attempt to set bit 12-15 to a zero
	pop		ax			;  Recover FLAG word
	and		ax, 0f000h	;  If Bits 12-15 are then the processor
	cmp		ax, 0f000h	;  is an 8018x or an 808x
	jz		is_0_1		
 
	mov		ax, 07000h	;  Try to set FLAG bits 12-14 (NT, IOPL)
	push 	ax
	popf					;  put 07000H into flags
	pushf
	pop		ax

	and		ax,07000h		;  if bits 12-14 are cleared then the
	jz		is_80286		;	processor is an 286

is_80386:					;	Else it is a 386 
	mov		ax, 386h		;	return 386 in AX
	jmp		done
is_80286:
	mov		ax, 286h		;  return 286 in AX
	jmp		done
is_0_1:					;It is a 8086 or a 80186
	push 	cx			;  Save CX the only other register used	
	mov		ax, 0ffffh	;  Set AX to all 1s
	mov		cl, 33		;  will shift it 33 times if it is an
						;  808x or 1 time if it is an 8018x
	shl		ax, cl		;  if we shift 33 times all bits are 
	jnz		is_80186		;  zero. If any bits are on it's an 18x 
is_8086:					;  Else we have an 8086
	mov		ax,86h		;  Return 86 in AX
	pop		cx			;  restore cx
	jmp		done	
	
is_80186:
	mov 		ax, 186h		;  Return 186 in AX
	pop		cx			

done:
	popf					; Recover original FLAG register
	ret

proc_type		endp

		
-- 
Clif Purkiser, Intel, Santa Clara, Ca.
{pur-ee,hplabs,amd,scgvaxd,dual,idi,omsvax}!intelca!clif

I guess I better put back the old disclaimer line.  These views
are my own property.  However anyone who wants them can have them.