home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / cpu / detect / det_cpu.asm next >
Assembly Source File  |  1990-08-18  |  4KB  |  117 lines

  1.  
  2. ;; Program to distinguish between 8086/80286/80386/80486
  3. ;; It does not trap illegal opcodes, and so works under virtual 8086
  4. ;; systems such as QEMM which cause other methods to crash.
  5. ;;
  6. ;; Notes: 1) It is possible for a monitor program that is handling a virtual
  7. ;; 8086 on an 80386 or 80486 to trap the instructions that access the
  8. ;; flags registers and make this code not work. But that would be a lot
  9. ;; of work to no purpose, so don't expect a problem in real life systems.
  10. ;; 2) This was only tested on an 80386 and an 80486. However, the code
  11. ;;   for 8086 and 80286 comes from an Intel manual and looks simple
  12. ;;
  13. ;; Acknowledgements:
  14. ;; This program gets its output code from a PC Magazine program that uses
  15. ;;   invalid opcode trapping and doesn't work under QEMM
  16. ;; The code to distinguish 8086 fro 80286 from 80386/486 is adapted from
  17. ;;   page 22-2 of the Untel 80486 Programmers Manual
  18. ;; The code to distiguish between 80386 and 80486 is adapted from pg 3-23
  19. ;;   of the same manual. Note that the comments in the manual describe
  20. ;;   the return value backwards.
  21. ;; The comments are my own
  22. ;;
  23. ;; Sidney Markowitz <sidney@saturn.ucsc.edu> or <sidney@ai.mit.edu>
  24.  
  25.         .MODEL  TINY
  26.  
  27. DOS     equ     21H
  28. DosPrint equ    09H
  29. DosExit equ     4CH
  30.  
  31.         .DATA
  32. CPUMSG  DB      0DH,0AH,'CPU is an 80$'
  33. I86     DB      '86$'
  34. I286    DB      '286$'
  35. I386    DB      '386$'
  36. I486    DB      '486$'
  37. CRLF    DB      0DH,0AH,'$'
  38.  
  39.         .CODE
  40.         ORG     100H
  41.         .386p   ;; allow 386 style assembler instructions
  42. prog:
  43.         mov     ah,DosPrint
  44.         mov     dx,offset CPUMSG
  45.         int     DOS
  46.  
  47. ;; Test for 8086 by trying to set flags high nibble to 0
  48. ;; On an 8086, the nibble will remain all ones
  49.         mov     dx,offset I86
  50.         pushf
  51.         pop     bx
  52.         and     bh,0Fh
  53.         push    bx
  54.         popf
  55.         pushf
  56.         pop     ax
  57.         and     ah,0F0h
  58.         cmp     ah,0F0h
  59.         je      TELLCPU    ; print out that this is an 8086
  60.  
  61. ;; Test for 80286 by trying to set flags high nibble to all ones.
  62. ;; On an 80286, the nibble will remain all zeroes
  63.         mov     dx,offset I286
  64.         or      bh,0F0h
  65.         push    bx
  66.         popf
  67.         pushf
  68.         pop     ax
  69.         test    ah,0F0h
  70.         jz      TELLCPU
  71.  
  72. ;; Distinguish an 80386 from an 80486
  73. ;; Bit 18 (40000H) of EFLAGS register is used only in the 486
  74. ;; This code flips it and tests if anything happened.
  75. ;;
  76. ;;
  77.         mov     edx,esp      ; Save stack pointer
  78.         and     esp,not 3    ; Align stack pointer to prevent a fault
  79.                              ;  when we set the AC flag on a 486
  80.         pushfd               ; Copy the EFLAGS register
  81.         pop     eax          ;   into register eax
  82.         mov     ecx,eax      ; Save the original EFLAGS value
  83.         xor     eax,40000H   ; Flip the AC flag bit
  84.         push     eax         ; Try to put the modified value back
  85.         popfd                ;   into the EFLAGS register
  86.         pushfd               ; Copy the EFLAGS register again
  87.         pop     eax          ;   into eax
  88.         xor     eax,ecx      ; Compare the old and new AC bits
  89.         shr     eax,18       ; Shift and mask to get the AC comparison bit
  90.         and     eax,1        ;   in the low order position of eax
  91.         push    ecx
  92.         popfd                ; Restore EFLAGS that were saved on entry
  93.         mov     esp,edx      ; And restore stack pointer to saved value
  94. ;;
  95. ;; at this point ax = 0 on a 386
  96. ;;               ax = 1 on a 486
  97.         mov     dx,offset I386
  98.         test    ax,ax
  99.         jz      TELLCPU
  100.         mov     dx,offset I486
  101.  
  102. ;; output a message with the result, then exit
  103.  
  104. TELLCPU:
  105.         mov     ah,DosPrint
  106.         int     DOS
  107.         mov     ah,DosPrint
  108.         mov     dx,offset CRLF
  109.         int     DOS
  110.         mov     al,0
  111.         mov     ah,DosExit
  112.         int     DOS
  113.         end     prog
  114. ;;;; end of program ;;;;;;;;
  115.  
  116.  
  117.