home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / cpu.zoo / cpu.4 < prev   
Internet Message Format  |  1989-08-18  |  8KB

  1. From santra!kth!sunic!mcvax!uunet!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!csd4.csd.uwm.edu!mailrus!jarvis.csri.toronto.edu!utgpu!utzoo!mnetor!tmsoft!mshiels Fri Aug 18 10:31:43 EET DST 1989
  2. Article 7096 of comp.sys.ibm.pc:
  3. Path: chyde!santra!kth!sunic!mcvax!uunet!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!csd4.csd.uwm.edu!mailrus!jarvis.csri.toronto.edu!utgpu!utzoo!mnetor!tmsoft!mshiels
  4. >From: mshiels@tmsoft.uucp (Michael A. Shiels)
  5. Newsgroups: comp.sys.ibm.pc
  6. Subject: CPU Identification 4 of 4
  7. Message-ID: <1989Aug16.110629.484@tmsoft.uucp>
  8. Date: 16 Aug 89 11:06:29 GMT
  9. Reply-To: mshiels@tmsoft.UUCP (Michael A. Shiels)
  10. Followup-To: comp.sys.ibm.pc
  11. Organization: MaS Network Software and Consulting
  12. Lines: 175
  13.  
  14. Article 27332 of comp.sys.ibm.pc:
  15. Xref: tmsoft comp.sys.ibm.pc:27332 comp.sys.intel:780
  16. Path: tmsoft!dptcdc!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!bloom-beacon!usc!orion.cf.uci.edu!uci-ics!zardoz!conexch!rob
  17. >From: rob@conexch.UUCP (Robert Collins)
  18. Newsgroups: comp.sys.ibm.pc,comp.sys.intel
  19. Subject: Source code to determing 80486 CPU
  20. Keywords: 80486
  21. Message-ID: <30106@conexch.UUCP>
  22. Date: 28 May 89 02:56:58 GMT
  23. Organization: The Consultants' Exchange, Orange County, CA
  24. Lines: 163
  25.  
  26. ;-----------------------------------------------------------------------------
  27. ; CPU_Type determines the CPU type in the system.
  28. ;-----------------------------------------------------------------------------
  29. ; Written by:
  30. ;   Robert Collins
  31. ;   3361 Keys Lane
  32. ;   Anaheim, CA  92804
  33. ;-----------------------------------------------------------------------------
  34. ; Input:   None
  35. ; Output:  AX = CPU type
  36. ;           0 = 8086/8088
  37. ;           1 = 80186/80188
  38. ;           2 = 80286
  39. ;           3 = 80386
  40. ;           4 = 80486
  41. ;        FFFF = Unknown CPU type
  42. ;-----------------------------------------------------------------------------
  43.  
  44. .radix 16                       ; anybody that programs in base 10 is a wimp!
  45. .386P                           ; MASM 5.1 directive
  46.  
  47. ;-----------------------------------------------------------------------------
  48. ; PUBLIC statements here
  49. ;-----------------------------------------------------------------------------
  50.         Public  CPU_Type
  51.  
  52. ;-----------------------------------------------------------------------------
  53. ; Local variable definitions
  54. ;-----------------------------------------------------------------------------
  55.         INT6    equ     [bp-4]
  56.  
  57. ;-----------------------------------------------------------------------------
  58. ; Interrupt vector segment
  59. ;-----------------------------------------------------------------------------
  60. ABS0    segment use16 at 0
  61.  
  62.         org 6*4
  63. Orig_INT6       dd      ?
  64.  
  65. ABS0    ends
  66.  
  67.  
  68. ;-----------------------------------------------------------------------------
  69. ; 80486 instruction macro -- because MASM 5.1 doesn't support the 80486!
  70. ;-----------------------------------------------------------------------------
  71. XADD    macro
  72.         db      0fh,0C0h,0D2h           ; 80486 instruction macro
  73. ENDM
  74.  
  75.  
  76. cseg    segment para    use16 public 'code'
  77.         assume  cs:cseg
  78.  
  79. CPU_Type        proc    near
  80. ;-----------------------------------------------------------------------------
  81. ; Determine the CPU type by testing for differences in the CPU in the system.
  82. ;-----------------------------------------------------------------------------
  83. ; To test for the 8086/8088, test the value of SP after it is placed on the
  84. ; stack.  The 8086/8088 increments this value before pushing it on the stack,
  85. ; all other CPU's increment SP after pushing it on the stack.
  86. ;-----------------------------------------------------------------------------
  87.         xor     ax,ax                   ; clear CPU type return register
  88.         push    sp                      ; save SP on stack to look at
  89.         pop     bx                      ; get SP saved on stack
  90.         cmp     bx,sp                   ; if 8086/8088, these values will differ
  91.         jnz     CPU_8086_exit           ; yep
  92. ;-----------------------------------------------------------------------------
  93. ; When we get here, we know that we aren't a 8086/8088.  And since all
  94. ; subsequent processors will trap invalid opcodes via INT6, we will determine
  95. ; which CPU we are by trapping an invalid opcode.
  96. ;   We are an 80486 if:  XADD   DX,DX   executes correctly
  97. ;             80386 if:  MOV    EDX,CR0 executes correctly
  98. ;             80286 if:  SMSW   DX      executes correctly
  99. ;             80186 if:  SHL    DX,5    executes correctly
  100. ;-----------------------------------------------------------------------------
  101. ; Setup INT6 handler
  102. ;-----------------------------------------------------------------------------
  103.         enter   4,0                     ; create stack frame
  104.         mov     word ptr INT6,offset INT6_handler
  105.         mov     INT6+2,cs
  106.         call    set_INT6_vector         ; set pointer to our INT6 handler
  107.         mov     ax,4                    ; initialize CPU flag=4 (80486)
  108.         xor     cx,cx                   ; initialize semaphore
  109.  
  110. ;-----------------------------------------------------------------------------
  111. ; Now, try and determine which CPU we are by executing invalid opcodes.
  112. ; The instructions I chose to invoke invalid opcodes, are themselves rather
  113. ; benign.  In each case, the chosen instruction modifies the DX register,
  114. ; and nothing else.  No system parameters are changed, e.g. protected mode,
  115. ; or other CPU dependant features.
  116. ;-----------------------------------------------------------------------------
  117. ; The 80486 instruction 'XADD' xchanges the registers, then adds them.
  118. ; The exact syntax for a '486 compiler would be:  XADD  DX,DX.
  119. ;-----------------------------------------------------------------------------
  120.         XADD   ;DX,DX                   ; 80486
  121.         jcxz    CPU_exit
  122.         dec     ax                      ; set 80386 semaphore
  123.         inc     cx                      ; CX=0
  124.  
  125. ;-----------------------------------------------------------------------------
  126. ; For a description on the effects of the following instructions, look in
  127. ; the Intel Programmers Reference Manual's for the 80186, 80286, or 80386.
  128. ;-----------------------------------------------------------------------------
  129.         mov     edx,cr0                 ; 80386
  130.         jcxz    CPU_exit
  131.         dec     ax                      ; set 80286 semaphore
  132.         inc     cx                      ; CX=0
  133.  
  134.         smsw    dx                      ; 80286
  135.         jcxz    CPU_exit
  136.         dec     ax                      ; set 80186 semaphore
  137.         inc     cx                      ; CX=0
  138.  
  139.         shl     dx,5                    ; 80186/80188
  140.         jcxz    CPU_exit
  141.         dec     ax                      ; set UNKNOWN_CPU semaphore
  142.  
  143. CPU_exit:
  144.         call    set_INT6_vector
  145.         leave
  146.  
  147. CPU_8086_exit:
  148.         ret
  149.  
  150.  
  151. ;-----------------------------------------------------------------------------
  152. ; Set the INT6 vector by exchanging it with the one currently on the stack.
  153. ;-----------------------------------------------------------------------------
  154. set_INT6_vector:
  155.         push    ds
  156.         push    ABS0                    ; save interrupt vector segment
  157.         pop     ds                      ; make DS=INT vector segment
  158.         mov     dx,word ptr ds:Orig_INT6;       ; get offset if INT6 handler
  159.         xchg    INT6,dx                 ; set new INT6 offset
  160.         mov     word ptr ds:Orig_INT6,dx
  161.         mov     dx,word ptr ds:Orig_INT6+2      ; get segment of INT6 handler
  162.         xchg    INT6+2,dx               ; set new INT6 segment
  163.         mov     word ptr ds:Orig_INT6+2,dx
  164.         pop     ds                      ; restore segment register
  165.         ret                             ; split
  166.  
  167.  
  168. ;-----------------------------------------------------------------------------
  169. ; INT6 handler sets a semaphore (CX=FFFF) and adjusts the return address to
  170. ; point past the invalid opcode.
  171. ;-----------------------------------------------------------------------------
  172. INT6_handler:
  173.         enter   0,0                     ; create new stack frame
  174.         dec     cx                      ; make CX=FFFF
  175.         add     word ptr ss:[bp][2],3   ; point past invalid opcode
  176.         leave
  177.         iret
  178.  
  179. CPU_Type        endp
  180.  
  181. cseg    ends
  182.         end
  183.  
  184. -- 
  185. "Worship the Lord your God, and serve him only."  Mat. 4:10
  186. Robert Collins                 UUCP:  ucbvax!ucivax!icnvax!conexch!rob
  187. HOMENET:  (805) 523-3205       UUCP:  uunet!ccicpg!turnkey!conexch!rob
  188. WORKNET:  (805) 378-7901
  189.  
  190.  
  191.