home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / cpu_id.zip / CPUID.ASM < prev    next >
Assembly Source File  |  1994-09-20  |  7KB  |  216 lines

  1.     TITLE CPUID
  2.         
  3. comseg  segment
  4.  
  5.         org    100h
  6.  
  7.     assume  cs:comseg,ds:comseg,es:comseg,ss:comseg
  8.  
  9. cpuid   proc    near 
  10.     
  11.     mov     dx,00feh
  12.     mov     sp,dx
  13.     jmp     start
  14.  
  15.     fp_status       dw      ?
  16.     id_mess         db      "This system has a$"
  17.     fp_8087         db      " and an 8087 Math CoProcessor$"
  18.     fp_80287        db      " and a 287tm Math CoProcessor$"
  19.     fp_80387        db      " and a 387tm Math CoProcessor$"
  20.     c8086           db      "n 8086/8088 Microprocessor$"
  21.     c286            db      "n 80286 Microprocessor$"
  22.     c386            db      " 386tm Microprocessor$"
  23.     c486            db      " 486-DXtm Microprocessor/487tm Math CoProcessor$"
  24.     c486nfp         db      " 486-SXtm Microprocessor$"
  25.     period          db      ".",0dh,0ah,"$"
  26.     present_86      dw      0
  27.     present_286     dw      0
  28.     present_386     dw      0
  29.     present_486     dw      0
  30.  
  31. start:
  32.     mov     dx,offset id_mess  ; print header message
  33.     mov     ah,9h
  34.     int     21h
  35.  
  36.  ;
  37.  ;      8086 check
  38.  ;      Bits 12-15 are always set on the 8086 processor.
  39.  ;
  40.  
  41.     pushf                   ; save EFLAGS
  42.     pop     bx              ; store EFLAGS in BX
  43.     mov     ax,0fffh        ; clear bits 12-15
  44.     and     ax,bx           ; in EFLAGS
  45.     push    ax              ; store new EFLAGS value on stack
  46.     popf                    ; replace current EFLAGS value
  47.     pushf                   ; set new EFLAGS
  48.     pop     ax              ; store new EFLAGS in AX
  49.     and     ax,0f000h       ; if bits 12-15 are set, then CPU
  50.     cmp     ax,0f000h       ; is an 8086/8088
  51.     mov     dx,offset c8086 ; store 8086/8088 message
  52.     mov     present_86,1    ; turn on 8086/8088 flag
  53.     je      check_fpu       ; if CPU is 8086/8088, check for
  54.                 ; 8087
  55.  
  56.  ;
  57.  ;      80286 CPU Check
  58.  ;      Bits 12-15 are always clear on the 80286 processor.
  59.  ;
  60.  
  61.     or      bx,0f000h       ; try to set bits 12-15
  62.     push    bx
  63.     popf
  64.     pushf
  65.     pop     ax
  66.     and     ax,0f000h       ; if bits 12-15 are cleared, then
  67.     mov     dx,offset c286  ;       CPU is an 80286
  68.     mov     Present_86,0    ; turn off 8086/8088 flag
  69.     mov     present_286,1   ; turn on 80286 flag
  70.     je      check_fpu       ; if CPU is 80286, check for 80287
  71.  
  72. ;
  73. ;       386 CPU check
  74. ;
  75. ;       The AC bit, bit #18, is a new bit introduced in the EFLAGS
  76. ;       on the 486 DX CPU to generate alignment faults.  This bit can 
  77. ;       be set on the 486 DX CPU, but not on the 386 CPU.
  78. ;
  79.  
  80.     mov     bx,sp           ; save current stack pointer to
  81.                 ;     align it
  82.     and     sp,not 3        ; align stack to avoid AC fault
  83.     db      66h
  84.     pushf                   ; push original EFLAGS
  85.     db      66h
  86.     pop     ax              ; get original EFLAGS
  87.     db      66h
  88.     mov     cx,ax           ; save original EFLAGS
  89.     db      66h             
  90.     xor     ax,0            ; xor EAX,40000h
  91.                 ;    flip AC bit in EFLAGS
  92.     dw      4               ; upper 16-bits of xor constant
  93.     db      66h
  94.     push    ax              ; save for EFLAGS
  95.     db      66h
  96.     popf                    ; copy to EFLAGS
  97.     db      66h
  98.     pushf                   ; push EFLAGS
  99.     db      66h
  100.     pop     ax              ; get new EFLAGS value
  101.     db      66h
  102.     xor     ax,cx           ; if AC bit cannot be changed,
  103.                 ;   CPU is
  104.     mov     dx,offset c386  ; store 386 message
  105.     mov     present_286,0   ; turn off 80286 flag
  106.     mov     present_386,1   ; turn on 386 flag
  107.     je      check_fpu       ; if CPU is 386, now check for
  108.                 ;   80287/80387
  109.  
  110. ;
  111. ;       486 DX CPU and 486 DX CPU w/o FPU checking
  112. ;
  113.  
  114.     mov     dx,offset c486nfp  ; store 486NFP(SX) message
  115.     mov     present_386,0      ; turn off 386 flag
  116.     mov     present_486,1      ; turn on 486 flag
  117.  
  118.  
  119.  check_fpu:                     ; check for 8087/80287/80387
  120.     
  121.     fninit                  ; reset FP status word
  122.     mov    fp_status,5a5ah  ; initialize temp word to non-zero
  123.                 ;    value
  124.     fnstsw fp_status        ; save FP status word
  125.     mov    ax,fp_status     ; check FP status word
  126.     cmp    al,0             ;   see if correct status with
  127.                 ;      written
  128.     jne    print_one        ; jump if not Valid, no NPX
  129.                 ;     installed
  130.     fnstcw  fp_status       ; save FP control word
  131.     mov    ax,fp_status     ; check FP control word
  132.     and    ax,103fh         ; see if selected parts looks OK
  133.     cmp    ax,3fh           ; check that ones and zeroes
  134.                 ;     correctly read
  135.     jne    print_one        ; jump if not Valid, no NPX
  136.                 ;     installed
  137.     cmp    present_486,1    ; check if 486 flag is on
  138.     je     is_486           ; if so, jump to print 486 message
  139.     jmp    not_486          ; else continue with 386 checking
  140.  
  141.  
  142.  is_486:
  143.     mov    dx,offset c486   ; store 486 message
  144.     jmp    print_one
  145.  
  146.  
  147.  not_486:
  148.     cmp     present_386,1   ; check if 386 flag is on
  149.     jne     print_87_287    ; if 386 flag not on, check NPX for
  150.                 ;       8086/8088/80286
  151.     mov     ah,9h           ; print out 386 CPU ID first
  152.     int     21h
  153.  
  154. ;
  155. ;       80287/80387 check for the 386 CPU
  156. ;
  157.  
  158.     fld1                    ; must use default control from
  159.                 ;     FNINIT
  160.     fldz                    ; form infinity
  161.     fdiv                    ; 8087/80287 says +inf = inf
  162.     fld     st              ; form negative infinity
  163.     fchs                    ; 80387 says +inf < > -inf
  164.     fcompp                  ; see if they are the same and
  165.                 ;    remove them
  166.     fstsw   fp_status       ; look at status from FCOMPP
  167.     mov     ax,fp_status
  168.     mov     dx,offset fp_80287      ; store 80287 message
  169.     sahf                            ; see if infinities matched
  170.     jz      restore_EFLAGS          ; jump if 8087/80287 is present
  171.     mov     dx,offset fp_80387      ; store 80387 message
  172.  
  173.  
  174.  restore_EFLAGS:
  175.         
  176.     finit                   ; clear any pending fp exception
  177.     mov     ah,9h           ; print NPX message
  178.     int     21h
  179.     db      66h
  180.     push    cx              ; push ECX
  181.     db      66h
  182.     popf                    ; restore original EFLAGS register
  183.     mov     sp,bx           ; restore original stack pointer
  184.     jmp     exit
  185.  
  186.  print_one:
  187.  
  188.     mov     ah,9h           ; print Out CPU ID with no NPX
  189.     int     21h
  190.     jmp     exit
  191.  
  192.  print_87_287:
  193.  
  194.     mov     ah,9h               ; print out 8086/8088/80286 first
  195.     int     21h
  196.     cmp     present_86,1        ; if 8086/8088 flag is on
  197.     mov     dx,offset fp_8087   ; store 8087 message
  198.     je      print_fpu
  199.     mov     dx,offset fp_80287  ; else CPU = 80286, store 80287
  200.                     ;     message
  201.  
  202.  print_fpu:
  203.   
  204.     mov     ah,9h               ; print out NPX
  205.     int     21h
  206.     jmp     exit
  207.  
  208.  exit:
  209.     mov     dx,offset period    ; print out a period of end message
  210.     mov     ah,9h
  211.     int     21h
  212.     mov     ax,4c00h           ; terminate program
  213.     int     21h
  214.  
  215.     end     cpuid
  216.