home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 17 / CD_ASCQ_17_101194.iso / vrac / cpu_id.zip / INTELCPU.TXT < prev    next >
Text File  |  1994-09-20  |  10KB  |  260 lines

  1.  
  2.      The following text has been copied exactly as is from the
  3.      _Intel486TM DX Microprocessor Data Book_, including any
  4.      and all printing errors.  Use at your own risk.  I found
  5.      a few typos in here while writing my own program!
  6.  
  7. ════════════════════════════════════════════════════════════════════════════
  8. ────────────────────────────────────────────────────────────────────────────
  9.             Intel486TM DX MICROPROCESSOR
  10. ────────────────────────────────────────────────────────────────────────────
  11.                 APPENDIX A
  12.         INTEL RECOMMENDED CPU IDENTIFICATION CODE
  13.  
  14.  The CPU identification assembly code will determine for the user which 
  15.  Intel microprocessor and if a Intel Math CoProcessor is installed in the 
  16.  system.  If a 486 microprocessor has been installed, the program will 
  17.  determine if the CPU is with/without a floating point unit.  This code 
  18.  should be executed so the system can be configured for a particular 
  19.  application, which may depend on the microprocessor and Math CoProcessor 
  20.  installed in the system.
  21. ────────────────────────────────────────────────────────────────────────────
  22.         TITLE CPUID
  23.         DOSSEG
  24.         .model  small
  25.  
  26.         .stack  100h
  27.  
  28.         .data
  29.     fp_status       dw      ?
  30.     id_mess         db      "This system has a$"
  31.     fp_8087         db      "and an 8087 Math CoProcessor$"
  32.     fp_80287        db      "and an 287tm Math CoProcessor$"
  33.     fp_80387        db      "and an 387tm Math CoProcessor$"
  34.     c8086           db      "n8086/8088 microprocessor$"
  35.     c286            db      "n80286 microprocessor$"
  36.     c386            db      "386tm microprocessor$"
  37.     c486            db      "486tm DX microprocessor/487tm SXtm Math
  38.                 "CoProcessor$"
  39.     c486nfp         db      "486tm SXtm Microprocessor$"
  40.     period          db      ".$",13,10
  41.     present_86      dw      0
  42.     present_286     dw      0
  43.     present_386     dw      0
  44.     present_486     dw      0
  45.  
  46. ;
  47. ;   The purpose of this code is to allow the user the ability to identify
  48. ;   the processor and coprocesor that is currently in the system.  The
  49. ;   algorithm of the program is to first determine the processor id.
  50. ;   When that is accomplished, the program continues to then identify
  51. ;   whether a coprocessor exists in the system.  If a coprocessor or
  52. ;   integrated coprocessor exists, the program will identify the
  53. ;   coprocessor id.  If one does not exist, the program then terminates.
  54. ;
  55.     
  56.          .code
  57.  
  58.  start:
  59.     mov     ax,@data
  60.     mov     ds,ax                   ; set segment register
  61.     mov     dx,offset id_mess       ;print header message
  62.     mov     ah,9h
  63.     int     21h
  64. ────────────────────────────────────────────────────────────────────────────
  65.                      A-1
  66. ════════════════════════════════════════════════════════════════════════════
  67.             Intel486Tm DX MICROPROCESSOR
  68. ────────────────────────────────────────────────────────────────────────────
  69.  ;
  70.  ;      8086 check
  71.  ;      Bits 12-15 are always set on the 8086 processor.
  72.  ;
  73.     pushf                   ;save EFLAGS
  74.     pop     bx              ;store EFLAGS in BX
  75.     mov     ax,0fffh        ;clear bits 12-15
  76.     and     ax,bx           ;in EFLAGS
  77.     push    ax              ;store new EFLAGS value on stack
  78.     popf                    ;replace current EFLAGS value
  79.     pushf                   ;set new EFLAGS
  80.     pop     ax              ;store new EFLAGS in AX
  81.     and     ax,0f000h       ;if bits 12-15 are set, then CPU
  82.     cmp     ax,0f000h       ;is an 8086/8088
  83.     mov     dx,offset c8086 ;store 8086/8088 message
  84.     mov     present_86,1    ;turn on 8086/8088 flag
  85.     je      check_fpu       ;if CPU is 8086/8088, check for
  86.                 ;8087
  87.  ;
  88.  ;      80286 CPU Check
  89.  ;      Bits 12-15 are always clear on the 80286 processor.
  90.  ;
  91.     or      bx,0f000h       ;try to set bits 12-15
  92.     push    bx
  93.     popf
  94.     pushf
  95.     pop     ax
  96.     and     ax,0f000h       ; if bits 12-15 are cleared, then
  97.     mov     dx,offset c286  ;       CPU is an 80286
  98.     mov     Present_86,0    ; turn off 8086/8088 flag
  99.     mov     present_286,1   ; turn on 80286 flag
  100.     jz      check_fpu       ; if CPU is 80286, check for 80287
  101. ;
  102. ;       386 CPU check
  103. ;
  104. ;       The AC bit, bit #18, is a new bit introduced in the EFLAGS
  105. ;       on the 486 DX CPU to generate alignment faults.  This bit can be set
  106. ;       on the 486 DX CPU, but not on the 386 CPU.
  107. ;
  108.     mov     bx,sp           ;save current stack pointer to
  109.                 ;align it
  110.     and     sp,not 3        ;align stack to avoid AC fault
  111.     db      66h
  112.     pushf                   ;push original EFLAGS
  113.     db      66h
  114.     pop     ax              ;get original EFLAGS
  115.     db      66h
  116.     mov     cx,ax           ;save original EFLAGS
  117.     db      66h             ;xor EAX,40000h
  118.     xor     ax,0            ;flip AC bit in EFLAGS
  119.     dw      4               ;upper 16-bits of xor constant
  120.     db      66h
  121.     push    ax              ;save for EFLAGS
  122.     db      66h
  123.     popf                    ;copy to EFLAGS
  124. ────────────────────────────────────────────────────────────────────────────
  125.                      A-2
  126. ════════════════════════════════════════════════════════════════════════════
  127.              Intel486Tm DX MICROPROCESSOR
  128. ────────────────────────────────────────────────────────────────────────────
  129.     db      66h
  130.     pushf                   ;push EFLAGS
  131.     db      66h
  132.     POP     ax              ;get new EFLAGS value
  133.     db      66h
  134.     xor     ax,cx           ;if AC bit cannot be changed,
  135.                 ;CPU is
  136.     mov     dx,offset c386  ;store 386 message
  137.     mov     present_286,0   ;turn off 80286 flag
  138.     mov     present_386,1   ;turn on 386 flag
  139.     Je      check_fpu       ;if CPU is 386, now check for
  140.                 ;80287/80387
  141. ;
  142. ;       486 DX CPU and 486 DX CPU w/o FPU checking
  143. ;
  144.     
  145.     mov     dx,offset c486nfp       ;store 486NFP message
  146.     mov     present_386,0           ;turn off 386 flag
  147.     mov     present_486,1           ;turn on 486 flag
  148.  
  149. ;
  150. ;    Co-processor checking begins here for the 8086/80286/386 CPUS.
  151. ;    The algorithm is to determine whether or not the floating-point
  152. ;    status and control words can be written to, the correct coprocessor
  153. ;    is then determined depending on the processor id. Coprocessor checks
  154. ;    are first performed for an 8086, 80286 and a 486 DX CPU.  If the
  155. ;    coprocessor id is still undetermined, the system must contain a 386
  156. ;    CPU. The 386 CPU may work with either an 80287 or an 80387.  The
  157. ;    infinity of the coprocessor must be checked to determine the correct
  158. ;    coprocessor id.
  159. ;
  160.  
  161. check_fpu:                      ;check for 8087/80287/80387
  162.     
  163.     fninit                  ; reset FP status word
  164.     mov    fp_status.5a5ah  ;initialize temp word to non-zero
  165.                 ;value
  166.     fnstsw fp_status        ;save FP status word
  167.     mov    ax,fp_status     ;check FP status word
  168.     cmp    al,0             ; see if correct status with
  169.                 ; written
  170.     jne    print_one        ;jump if not Valid, no NPX
  171.                 ;installed
  172.     fnstcw  fp_status       ;save FP control word
  173.     mov    ax,fp_status     ;check FP control word
  174.     and    ax,103fh         ;see if selected parts looks OX
  175.     cmp    ax,3fh           ;check that ones and zeroes
  176.                 ;correctly read
  177.     jne    print_one        ;jump if not Valid, no NPX
  178.                 ;installed
  179.     cmp    present_486,1    ;check if 486 flag is on
  180.     je     is_486           ;if so, jump to print 486 message
  181.     jmp    not_486          ;else continue with 386 checking
  182.  
  183. is_486:
  184.     mov    dx,offset c486   ;store 486 message
  185.     jmp    print_one
  186. ────────────────────────────────────────────────────────────────────────────
  187.                    A-3
  188. ════════════════════════════════════════════════════════════════════════════
  189.             Intel486Tm DX MICROPROCESSOR
  190. ────────────────────────────────────────────────────────────────────────────
  191. not_486:        
  192.     cmp     present_386,1   ; check if 386 flag is on
  193.     jne     print_87_287    ; if 386 flag not on, check NPX for
  194.                 ;       8086/8088/80286
  195.     mov     ah,9h           ;       print out 386 CPU ID first
  196.     int     21h
  197. ;
  198. ;       80287/80387 check for the 386 CPU
  199. ;
  200.     fldl                    ;must use default control from
  201.                 ;FNINIT
  202.     fldz                    ;form infinity
  203.     fdiv                    ;8087/80287 says +inf = inf
  204.     fld     st              ;form negative infinity
  205.     fchs                    ;80387 says +inf < > -inf
  206.     fcompp                  ;see if they are the same and
  207.                 ;remove them
  208.     fstsw   fp_status       ;look at status from FCOMPP
  209.     
  210.     mov     ax,fp_status
  211.     mov     dx,offset fp_80287      ;store 80287 message
  212.     sahf                            ;see if infinities matched
  213.     jz      restore_EFLAGS          ;jump if 8087/80287 is present
  214.     mov     dx,offset fp_80387      ;store 80387 message
  215.  
  216.  restore_EFLAGS:
  217.         
  218.     finit                   ;clear any pending fp exception
  219.     mov     ah,9h           ;print NPX message
  220.     int     21h
  221.     db      66h
  222.     push    cx              ;push ECX
  223.     db      66h
  224.     popf                    ;restore original EFLAGS register
  225.     mov     sp,bx           ;restore original stack pointer
  226.     jmp     exit
  227.  
  228.  print_one:
  229.  
  230.     mov     ah,9h           ;print Out CPU ID with no NPX
  231.     int     21h
  232.     jmp     exit
  233.  
  234.  print_87_287:
  235.  
  236.     mov     ah,9h           ;print out 8086/8088/80286 first
  237.     int     21h
  238.     cmp     present_86,1        ;if 8086/8088 flag is on
  239.     mov     dx,offset fp_8087   ;store 8087 message
  240.     je      print_fpu
  241.     mov     dx,offset fp_80287  ;else CPU = 80286, store 80287
  242.                     ;message
  243.  print_fpu:
  244.   
  245.     mov     ah,9h           ;print out NPX
  246.     int     21h
  247.     jmp     exit
  248.  
  249. exit:
  250.     mov     dx,offset period    ;print out a period of end message
  251.     mov     ah,9h
  252.     int     21h
  253.     mov     ax,4c00h        ;terminate program
  254.     int     21h
  255.  
  256.     end     start
  257. ────────────────────────────────────────────────────────────────────────────
  258.                     A-4
  259. ════════════════════════════════════════════════════════════════════════════
  260.