• Please review our updated Terms and Rules here

Detect CPU type on 386 and lower

linuxlove

Veteran Member
Joined
Jan 11, 2009
Messages
1,018
Location
Auburn, AL
This should be possible since the packet driver for my network card in the PS/2 reports what CPU you have installed.
What I want to know is how can you do this? I just saw a little file but it only shows how to on the 186, not 8088/8086.
 
I don't know how to do that in a program, but it's easy with a program. :) I've used Snooper.exe for years, but if you want something smaller, I see that the little "CPU-identifier" does it too. I just tried it on a P1 and got this output:
Code:
WhichCPU V0.50 (c) by Michael Holin     //    Public Domain
WhichCPU ? for info

Looking for: 8088,8086,V20,V30,80188,80186,80286,80386sx,-dx,RapidCAD
             80486sx,-dx,-slc,-dlc,Pentium
CPU found  : Pentium
NPU found  : build in
It comes with source code for ASM and PAS as well if that helps you.

Snooper and CPU-identifier and be found here as snoop342.zip and wcpu050.zip.
 
There are several ways. The method I remember is similar to what is in the website I am linking to below. It mentions that it won't catch all 8018x models and I think there were some specialized routines to catch NEC V-series, some buggy steppings and some chips from AMD and Harris that were modified from the Intel design. I probably have magazines that describe other detection techniques.

http://www.rcollins.org/ddj/Sep96/Sep96.html
 
Last edited:
This is the code I used back in the day,

const
cpu8086 = 1;
cpu80286 = 2;
cpu80386 = 3;
cpu80486 = 4;


function WhatCPU : Byte; Assembler;
asm
mov DX, Cpu8086
push SP
pop AX
cmp SP, AX
jne @OUT

mov DX, Cpu80286
pushf
pop AX
or AX, 4000h
push AX
popf
pushf
pop AX
test AX, 4000h
je @OUT

mov DX, Cpu80386 {"DB 66h" converts instructions to '386}
db 66h; mov BX, SP {mov EBX, ESP}
db 66h, 83h, 0e4h, 0fch {and ESP, FFFC}
db 66h; pushf
db 66h; pop AX
db 66h; mov CX, AX
db 66h, 35h, 00h
db 00h, 04h, 00h {xor EAX, 00040000}
db 66h; push AX
db 66h; popf
db 66h; pushf
db 66h; pop AX
db 66h, 25h, 00h
db 00h, 04h, 00h {and EAX, 00040000}
db 66h, 81h, 0e1h, 00h
db 00h, 04h, 00h {and ECX, 00040000}
db 66h; cmp AX, CX
je @Not486
mov DX, Cpu80486
@Not486:
db 66h; push CX
db 66h; popf
db 66h; mov SP, BX
@OUT:
mov AX, DX
end;{function WhatCpu}


So yet another option there.

Cheers!
 
For a 386 and above I use:
CPU Identification utility v1.14 (c) 1997-2007 Jan Steunebrink
it will fit on a bootable floppy
 
I found a CPU detection routine in the source for HIMEM.EXE that I was perusing for unrelated reasons, thought I might add it here for reference and comparison. Original source is half english half german comments, luckily this function is mostly english though - I rewrote the function name and word "result" so it's all english..
Code:
;==================================
; Detect CPU Type
;==================================
; Result:   AX=1 => 8086
;              2 => 80286
;              3 => 80386
;==================================
DetectCPU       proc   near
                xor     AX, AX              ; Move 0 into the Flags register
                push    AX
                popf
                pushf                       ; Try and get it back out
                pop     AX
                and     AH, 0F0h            ; If the top four bits are set...
                cmp     AH, 0F0h
                je      short MC_8086       ; ...it's an 8086 machine
                mov     AX, 0F000h          ; Move F000h into the Flags register
                push    AX
                popf
                pushf                       ; Try and get it back out
                pop     AX
                and     AH, 0F0h            ; If the top four bits aren't set...
                jz      short MC_80286      ; ...it's an 80286 machine
                ; We're on an 80386 machine
                mov     AX, 3
                ret
MC_80286:       ; We're on an 80286 machine
                mov     AX, 2
                ret
MC_8086:        ; We're on an 8086 machine
                mov     AX, 1
                ret
DetectCPU       endp
 
You can differentiate between 808x and 8018x+/v20 with code like this:

;determine CPU type
mov ax,sp
pusha ;8086 treats pusha as a 2 byte nop or close enough
nop
cmp ax,sp
je .nov20
xchg ax,sp ;fix sp
or byte [BV.XFlags],1 ;V20/186 or higher detected
.nov20:

There is probably not much point in differentiating between 80186 and V20/30 since the V20 has all the official 186 instructions, unless you are specifically targeting the V20/30. Its only weak spots are that this is the only x86 CPU to not support the undocumented SALC (becomes an alias to xlat, use pushf; sbb foo,foo; popf instead), and changing the divide/multiply by 10 immediate constants in AAM/AAD is not possible. For the purposes of real mode programs, 186/v20/286 are all about the same.

Well I guess I just gave an easy way to find a V20/V30 specifically, using missing SALC opcode:

findV20:
mov bx,findV20 ;we just need BX pointing somewhere that doesn't change
xor ax,ax
cs salc
xchg ah,al
cmc ;switch carry flag - salc will toggle between al=00 and al=ff
cs salc
cmp ah,al ;was salc result the same both times?
je V20Found
jne nonV20

How's that for a bizarre instruction sequence, using a segment override with an undocumented opcode in case it might be an alias to a different instruction...
 
Last edited:
Code:
DIM ArrayCPU(1 TO 4) AS STRING
ArrayCPU(1) = "8086/8088"
ArrayCPU(2) = "80186"
ArrayCPU(3) = "80286"
ArrayCPU(4) = "80386"

PRINT "Please identify your CPU type:"
FOR n = 1 TO 4
  PRINT STR$(ArrayCPU(n)) + ". " + ArrayCPU(n)
NEXT n
PRINT "Select the appropriate number... ";
DO
  key$ = INKEY$
  SELECT CASE key$
    CASE "1", "2", "3", "4"
      PRINT key$
      EXIT DO
  END SELECT
LOOP
PRINT
PRINT "Your CPU appears to be: " + ArrayCPU(VAL(key$))

:)
 
Mike:

BTW, I was going to run Wolf3D on my 486 to see what was going on, but I changed out my AM486 DX4-100 to a POD (83 MHz) and now I'm getting some a fatal exception error @ 0167:BFF99B6B. So this has had me tied up all weekend. As soon as I can tear it down and put the AMD back in I get on it.

P.S. Wouldn't happen to know what that error is - think its about two things trying to happen in the same place at the same time. What ever it is, WIN98SE dosen't like the POD. System does run real nice as long as its not 'blue screening'.
 
Back
Top