Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

CPU Identification 4 of 4

12 views
Skip to first unread message

Michael A. Shiels

unread,
Aug 16, 1989, 7:06:29 AM8/16/89
to
Article 27332 of comp.sys.ibm.pc:
Xref: tmsoft comp.sys.ibm.pc:27332 comp.sys.intel:780
Path: tmsoft!dptcdc!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!bloom-beacon!usc!orion.cf.uci.edu!uci-ics!zardoz!conexch!rob
From: r...@conexch.UUCP (Robert Collins)
Newsgroups: comp.sys.ibm.pc,comp.sys.intel
Subject: Source code to determing 80486 CPU
Keywords: 80486
Message-ID: <30...@conexch.UUCP>
Date: 28 May 89 02:56:58 GMT
Organization: The Consultants' Exchange, Orange County, CA
Lines: 163

;-----------------------------------------------------------------------------
; CPU_Type determines the CPU type in the system.
;-----------------------------------------------------------------------------
; Written by:
; Robert Collins
; 3361 Keys Lane
; Anaheim, CA 92804
;-----------------------------------------------------------------------------
; Input: None
; Output: AX = CPU type
; 0 = 8086/8088
; 1 = 80186/80188
; 2 = 80286
; 3 = 80386
; 4 = 80486
; FFFF = Unknown CPU type
;-----------------------------------------------------------------------------

.radix 16 ; anybody that programs in base 10 is a wimp!
.386P ; MASM 5.1 directive

;-----------------------------------------------------------------------------
; PUBLIC statements here
;-----------------------------------------------------------------------------
Public CPU_Type

;-----------------------------------------------------------------------------
; Local variable definitions
;-----------------------------------------------------------------------------
INT6 equ [bp-4]

;-----------------------------------------------------------------------------
; Interrupt vector segment
;-----------------------------------------------------------------------------
ABS0 segment use16 at 0

org 6*4
Orig_INT6 dd ?

ABS0 ends


;-----------------------------------------------------------------------------
; 80486 instruction macro -- because MASM 5.1 doesn't support the 80486!
;-----------------------------------------------------------------------------
XADD macro
db 0fh,0C0h,0D2h ; 80486 instruction macro
ENDM


cseg segment para use16 public 'code'
assume cs:cseg

CPU_Type proc near
;-----------------------------------------------------------------------------
; Determine the CPU type by testing for differences in the CPU in the system.
;-----------------------------------------------------------------------------
; To test for the 8086/8088, test the value of SP after it is placed on the
; stack. The 8086/8088 increments this value before pushing it on the stack,
; all other CPU's increment SP after pushing it on the stack.
;-----------------------------------------------------------------------------
xor ax,ax ; clear CPU type return register
push sp ; save SP on stack to look at
pop bx ; get SP saved on stack
cmp bx,sp ; if 8086/8088, these values will differ
jnz CPU_8086_exit ; yep
;-----------------------------------------------------------------------------
; When we get here, we know that we aren't a 8086/8088. And since all
; subsequent processors will trap invalid opcodes via INT6, we will determine
; which CPU we are by trapping an invalid opcode.
; We are an 80486 if: XADD DX,DX executes correctly
; 80386 if: MOV EDX,CR0 executes correctly
; 80286 if: SMSW DX executes correctly
; 80186 if: SHL DX,5 executes correctly
;-----------------------------------------------------------------------------
; Setup INT6 handler
;-----------------------------------------------------------------------------
enter 4,0 ; create stack frame
mov word ptr INT6,offset INT6_handler
mov INT6+2,cs
call set_INT6_vector ; set pointer to our INT6 handler
mov ax,4 ; initialize CPU flag=4 (80486)
xor cx,cx ; initialize semaphore

;-----------------------------------------------------------------------------
; Now, try and determine which CPU we are by executing invalid opcodes.
; The instructions I chose to invoke invalid opcodes, are themselves rather
; benign. In each case, the chosen instruction modifies the DX register,
; and nothing else. No system parameters are changed, e.g. protected mode,
; or other CPU dependant features.
;-----------------------------------------------------------------------------
; The 80486 instruction 'XADD' xchanges the registers, then adds them.
; The exact syntax for a '486 compiler would be: XADD DX,DX.
;-----------------------------------------------------------------------------
XADD ;DX,DX ; 80486
jcxz CPU_exit
dec ax ; set 80386 semaphore
inc cx ; CX=0

;-----------------------------------------------------------------------------
; For a description on the effects of the following instructions, look in
; the Intel Programmers Reference Manual's for the 80186, 80286, or 80386.
;-----------------------------------------------------------------------------
mov edx,cr0 ; 80386
jcxz CPU_exit
dec ax ; set 80286 semaphore
inc cx ; CX=0

smsw dx ; 80286
jcxz CPU_exit
dec ax ; set 80186 semaphore
inc cx ; CX=0

shl dx,5 ; 80186/80188
jcxz CPU_exit
dec ax ; set UNKNOWN_CPU semaphore

CPU_exit:
call set_INT6_vector
leave

CPU_8086_exit:
ret


;-----------------------------------------------------------------------------
; Set the INT6 vector by exchanging it with the one currently on the stack.
;-----------------------------------------------------------------------------
set_INT6_vector:
push ds
push ABS0 ; save interrupt vector segment
pop ds ; make DS=INT vector segment
mov dx,word ptr ds:Orig_INT6; ; get offset if INT6 handler
xchg INT6,dx ; set new INT6 offset
mov word ptr ds:Orig_INT6,dx
mov dx,word ptr ds:Orig_INT6+2 ; get segment of INT6 handler
xchg INT6+2,dx ; set new INT6 segment
mov word ptr ds:Orig_INT6+2,dx
pop ds ; restore segment register
ret ; split


;-----------------------------------------------------------------------------
; INT6 handler sets a semaphore (CX=FFFF) and adjusts the return address to
; point past the invalid opcode.
;-----------------------------------------------------------------------------
INT6_handler:
enter 0,0 ; create new stack frame
dec cx ; make CX=FFFF
add word ptr ss:[bp][2],3 ; point past invalid opcode
leave
iret

CPU_Type endp

cseg ends
end

--
"Worship the Lord your God, and serve him only." Mat. 4:10
Robert Collins UUCP: ucbvax!ucivax!icnvax!conexch!rob
HOMENET: (805) 523-3205 UUCP: uunet!ccicpg!turnkey!conexch!rob
WORKNET: (805) 378-7901

0 new messages