home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
cpu
/
detect
/
det_cpu.asm
next >
Wrap
Assembly Source File
|
1990-08-18
|
4KB
|
117 lines
;; Program to distinguish between 8086/80286/80386/80486
;; It does not trap illegal opcodes, and so works under virtual 8086
;; systems such as QEMM which cause other methods to crash.
;;
;; Notes: 1) It is possible for a monitor program that is handling a virtual
;; 8086 on an 80386 or 80486 to trap the instructions that access the
;; flags registers and make this code not work. But that would be a lot
;; of work to no purpose, so don't expect a problem in real life systems.
;; 2) This was only tested on an 80386 and an 80486. However, the code
;; for 8086 and 80286 comes from an Intel manual and looks simple
;;
;; Acknowledgements:
;; This program gets its output code from a PC Magazine program that uses
;; invalid opcode trapping and doesn't work under QEMM
;; The code to distinguish 8086 fro 80286 from 80386/486 is adapted from
;; page 22-2 of the Untel 80486 Programmers Manual
;; The code to distiguish between 80386 and 80486 is adapted from pg 3-23
;; of the same manual. Note that the comments in the manual describe
;; the return value backwards.
;; The comments are my own
;;
;; Sidney Markowitz <sidney@saturn.ucsc.edu> or <sidney@ai.mit.edu>
.MODEL TINY
DOS equ 21H
DosPrint equ 09H
DosExit equ 4CH
.DATA
CPUMSG DB 0DH,0AH,'CPU is an 80$'
I86 DB '86$'
I286 DB '286$'
I386 DB '386$'
I486 DB '486$'
CRLF DB 0DH,0AH,'$'
.CODE
ORG 100H
.386p ;; allow 386 style assembler instructions
prog:
mov ah,DosPrint
mov dx,offset CPUMSG
int DOS
;; Test for 8086 by trying to set flags high nibble to 0
;; On an 8086, the nibble will remain all ones
mov dx,offset I86
pushf
pop bx
and bh,0Fh
push bx
popf
pushf
pop ax
and ah,0F0h
cmp ah,0F0h
je TELLCPU ; print out that this is an 8086
;; Test for 80286 by trying to set flags high nibble to all ones.
;; On an 80286, the nibble will remain all zeroes
mov dx,offset I286
or bh,0F0h
push bx
popf
pushf
pop ax
test ah,0F0h
jz TELLCPU
;; Distinguish an 80386 from an 80486
;; Bit 18 (40000H) of EFLAGS register is used only in the 486
;; This code flips it and tests if anything happened.
;;
;;
mov edx,esp ; Save stack pointer
and esp,not 3 ; Align stack pointer to prevent a fault
; when we set the AC flag on a 486
pushfd ; Copy the EFLAGS register
pop eax ; into register eax
mov ecx,eax ; Save the original EFLAGS value
xor eax,40000H ; Flip the AC flag bit
push eax ; Try to put the modified value back
popfd ; into the EFLAGS register
pushfd ; Copy the EFLAGS register again
pop eax ; into eax
xor eax,ecx ; Compare the old and new AC bits
shr eax,18 ; Shift and mask to get the AC comparison bit
and eax,1 ; in the low order position of eax
push ecx
popfd ; Restore EFLAGS that were saved on entry
mov esp,edx ; And restore stack pointer to saved value
;;
;; at this point ax = 0 on a 386
;; ax = 1 on a 486
mov dx,offset I386
test ax,ax
jz TELLCPU
mov dx,offset I486
;; output a message with the result, then exit
TELLCPU:
mov ah,DosPrint
int DOS
mov ah,DosPrint
mov dx,offset CRLF
int DOS
mov al,0
mov ah,DosExit
int DOS
end prog
;;;; end of program ;;;;;;;;