home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / chipsc / chipstc / chipstc.asm next >
Encoding:
Assembly Source File  |  1990-02-09  |  10.5 KB  |  262 lines

  1. page    60,132
  2. title   chips() - CPU and Math Coprocessor (NDP) Type Check
  3.  
  4. ;   calling convention:
  5. ;
  6. ;       int chips( void );
  7. ;
  8. ;   returns:
  9. ;
  10. ;       tucked away neatly in your AX....
  11. ;
  12. ;       you get back   8x if an 8088/8086
  13. ;                     18x if an 80186/80188
  14. ;                     28x if an 80286
  15. ;                     38x if an 80386
  16. ;                     20x for a NEC V20/V30
  17. ;                AND
  18. ;                     xx0 if NO NDP is found
  19. ;                     xx1 if an 8087
  20. ;                     xx2 if an 80287
  21. ;                     xx3 for an 80387
  22. ;
  23. ;   OR.....
  24. ;
  25. ;   >>> A return of 280 means you got an 80286 machine with no NDP, <<<
  26. ;   >>> 383 means you have an 80386/80387 rig to work with, and a   <<<
  27. ;   >>> return of 81 sez that you have 8088/8086 CPU with an 8087.  <<<
  28. ;   >>> A 200 tells you that you got an NEC V20/V30 without an NDP. <<<
  29. ;   >>> ETC., Etc., etc.                                            <<<
  30. ;
  31. ;   NOTE:
  32. ;
  33. ;       There are lotsa ways of handling the way this function returns
  34. ;       it's data.  For my purposes, I have elected this one because
  35. ;       it requires only int arithmetic on the caller's end to extract
  36. ;       all the info I need from the return value.  I think that I'm
  37. ;       well enough 'commented' in the following code so that you will
  38. ;       be able to tinker and Putz until you find the best return tech-
  39. ;       nique for Ur purposes without having to reinvent the wheel.
  40. ;
  41. ;     >>>>        Please see TEST.C, enclosed in this .ZIP.      <<<<
  42. ;
  43. ;   REFERENCES:
  44. ;
  45. ;     _chips is made up of two PROC's, cpu_type and ndp_type.
  46. ;
  47. ;       cpu_type is based on uncopyrighted, published logic by
  48. ;         Clif (that's the way he spells it) Purkiser of Intel -
  49. ;         Santa Clara.
  50. ;
  51. ;       ndp_type is adopted from Ted Forgeron's article in PC
  52. ;         Tech Journal, Aug '87 p43.
  53. ;
  54. ;     In the event of subsequent republication of this function,
  55. ;       please carry forward reference to these two gentlemen as
  56. ;       original authors.
  57. ;
  58. ;       Copr. 1987      Pat Shea - Psi! (that Copr. is on there cuz my
  59. ;                                        lawyer sez I should, but feel
  60. ;                                        free to hack away!!!    pats.)
  61. ;
  62. ;------------------------------------------------------------------------
  63. ;
  64. ;     02/09/90  -  Program modified to work with TurboC 2.0:
  65. ;
  66. ;     Here is a quick example of how the code is used from TurboC 2.0:
  67. ;
  68. ;
  69. ;         int  chips (void);         ; declare external CHIPS routine
  70. ;
  71. ;         main ()
  72. ;           {
  73. ;             return (chips ());     ; return result as DOS errorlevel
  74. ;           }
  75. ;
  76. ;
  77. ;     Notes:
  78. ;
  79. ;        1) You need to link the CHIPS.OBJ file into the
  80. ;           TurboC program with either a project file or
  81. ;           by adding it to you .LIB libaries.
  82. ;
  83. ;        2) The included CHIPS.OBJ file is compiled for
  84. ;           the Tiny, Small and Compact memory models.
  85. ;
  86. ;        3) To use thw Medium, Large and Huge memory
  87. ;           models refer to pp 366-367 of the Turbo C
  88. ;           User's Guide manual.
  89. ;
  90. ;        4) If you re-assemble this file make sure you use
  91. ;           case sensitivity on symbols (/ml switch for TASM)
  92. ;
  93. ;
  94. ;                                           - Henrik Schmiediche
  95. ;
  96.  
  97.  
  98. _TEXT   SEGMENT BYTE PUBLIC 'CODE'
  99.         ASSUME  CS:_TEXT,DS:DGROUP
  100.  
  101.         PUBLIC  _chips
  102.  
  103. _chips         PROC NEAR
  104.  
  105. control dw     0              ; control word needed for the NDP test
  106.  
  107.         push   BP             ; save where Ur at
  108.         mov    BP,SP          ;   going in.....
  109.         push   DI
  110.         push   SI
  111.         push   CX             ; not really needed for MSC but kinda
  112.                               ;   nice to do cuz someone else might
  113.                               ;   want to use the function and we do
  114.                               ;   use CX later on
  115.  
  116.         call   cpu_type       ; find out what kinda CPU you got and
  117.                               ;   and save it in DX for future reference
  118.         call   ndp_type       ; check for math coprocessor (NDP) type
  119.                               ;   and hold that result in AX
  120.  
  121.         add    AX,DX          ; add the two results together and hold
  122.                               ;   'em in AX for Ur return to the caller
  123.  
  124.         pop    CX             ; put things back the way that you
  125.         pop    SI             ;   found 'em when you started this
  126.         pop    DI             ;   little drill off.....
  127.         pop    BP
  128.                               ; AND
  129.         ret                   ; go back to where you came from....
  130.                               ;   ( ===>  the calling program )
  131.                               ;   with Ur results sittin' in AX !!
  132. _chips         endp
  133.  
  134.  
  135. cpu_type       PROC NEAR
  136.  
  137.         pushf                 ; pump Ur flags register onto the stack
  138.         xor    DX,DX          ; blow out Ur DX and AX to start off
  139.         xor    AX,AX          ;   with a clean slate
  140.         push   AX             ; put AX on the stack
  141.         popf                  ; bring it back in Ur flags
  142.         pushf                 ; try to set bits 12 thru 15 to a zero
  143.         pop    AX             ; get back Ur flags word in AX
  144.         and    AX, 0f000h     ; if bits 12 thru 15 are set then you got
  145.         cmp    AX, 0f000h     ;   an Intel 8018x or a 808x or maybe even
  146.         jz     dig            ;   a NEC V20/V30 ??? - gotta look more...
  147.  
  148. ; OTHERWISE....
  149. ;   Here's the BIG one.... 'tells the difference between an 80286 and
  150. ;   an 80386 !!
  151.  
  152.         mov    AX, 07000h     ; try to set FLAG bits 12 thru 14
  153.                               ;   - NT, IOPL
  154.         push   AX             ; put it onto the stack
  155.         popf                  ;   and try to pump 07000H into Ur flags
  156.         pushf                 ; push Ur flags, again
  157.         pop    AX             ;   and bring back AX for a compare
  158.         and    AX,07000h      ; if Ur bits 12 thru 14 are set
  159.         jnz    got386         ;   then Ur workin' with an 80386
  160.         mov    DX, 0280       ; save 280 in DX cuz it's an 80286
  161.         jmp    SHORT CPUbye   ;   and bail out
  162.  
  163. got386: mov    DX, 0380       ; save 380 in DX cuz it's an Intel 80386
  164.         jmp    SHORT CPUbye   ;   and bail out
  165.  
  166. ; here's we try to figger out whether it's an 80188/80186, an 8088/8086
  167. ;   or an NEC V20/V30 - 'couple of slick tricks from Clif Purkiser.....
  168.  
  169. dig:    mov    AX, 0ffffh     ; load up AX
  170.         mov    CL, 33         ; HERE's the FIRST TRICK.... this will
  171.                               ;   shift everything 33 times if it's
  172.                               ;   8088/8086, or once for a 80188/80186!
  173.         shl    AX, CL         ; on a shift of 33, all bits get zeroed
  174.         jz     digmor         ;   out so if anything is left ON it's
  175.                               ;   gotta be an 80188/80186
  176.         mov    DX,0180        ; save 180 in DX cuz it's an 80188/80186
  177.         jmp    SHORT CPUbye   ;   and bail out
  178.  
  179. digmor: xor    AL,AL          ; clean out AL to set ZF
  180.         mov    AL,40h         ; ANOTHER TRICK.... mul on an NEC duz NOT
  181.         mul    AL             ;   effect the zero flag BUT on an Intel
  182.         jz     gotNEC         ;   8088/8086, the zero flag gets thrown
  183.         mov    DX,0080        ; 80 into DX cuz it's an Intel 8088/8086
  184.         jmp    SHORT CPUbye   ;   and bail out
  185.  
  186. gotNEC: mov    DX,0200        ; it's an NEC V20/V30 so save 200 in DX
  187.  
  188. CPUbye: popf                  ; putchur flags back to where they were
  189.         ret                   ;   and go back to where you came from
  190.                               ;   (i.e., ===>  _chips) with the CPU type
  191.                               ;   tucked away in DX for future reference
  192. cpu_type       endp
  193.  
  194. ; Check for an NDP.
  195. ;
  196. ; >>>>NOTE:  If you are using an MASM version < 5.0, don't forget to
  197. ; use the /R option or you will bomb cuz of the coprocessor instruc-
  198. ; tions.  /R is not needed for version 5.0.<<<<<<<<<<<<<<<<<<<<<<<<<
  199.  
  200. ndp_type       PROC NEAR
  201.  
  202. do_we:  fninit                          ; try to initialize the NDP
  203.         mov    byte ptr control+1,0     ; clear memory byte
  204.         fnstcw control                  ; put control word in memory
  205.         mov    AH,byte ptr control+1    ; iff AH is 03h, you got
  206.         cmp    AH,03h                   ;   an NDP on board !!
  207.         je     chk_87                   ; found somethin', keep goin'
  208.         xor    AX,AX                    ; clean out AX to show a zero
  209.         jmp    SHORT NDPbye             ;   return (i.e., no NDP)
  210.  
  211. ; 'got an 8087 ??
  212.  
  213. chk_87: and    control,NOT 0080h        ; turn ON interrupts (IEM = 0)
  214.         fldcw  control                  ; load control word
  215.         fdisi                           ; turn OFF interrupts (IEM = 1)
  216.         fstcw  control                  ; store control word
  217.         test   control,0080h            ; iff IEM=1, 8087
  218.         jz     chk287                   ; 'guess not!  March on....
  219.         mov    AX,0001                  ; set up for a 1 return to
  220.         jmp    SHORT NDPbye             ;   show an 8087 is on board
  221.  
  222. ; if not.... would you believe an 80287 maybe ??
  223.  
  224. chk287: finit                 ; set default infinity mode
  225.         fld1                  ; make infinity
  226.         fldz                  ;   by dividing
  227.         fdiv                  ;   1 by zero !!
  228.         fld    st             ; now make a
  229.         fchs                  ;   negative infinity
  230.         fcompp                ; compare Ur two infinities
  231.         fstsw  control        ; iff, for 8087 or 80287
  232.         fwait                 ; sit tight 'til status word is put away
  233.         mov    AX,control     ; getchur control word
  234.         sahf                  ; putchur AH into flags
  235.         jnz    got387         ; NO GOOD.... march on !!
  236.         mov    AX,0002        ; gotta be a 80287 cuz we already tested
  237.         jmp    SHORT NDPbye   ;   for an 8087
  238.  
  239. ; We KNOW that there is an NDP on board otherwise we would have bailed
  240. ; out after 'do_we'.  It isn't an 8087 or an 80287 or we wouldn't have
  241. ; gotten this far.  It's gotta be an 80387 !!
  242.  
  243. got387: mov    AX,0003        ; call it an 80387 and return 3
  244.  
  245. NDPbye: ret                   ; and go back where you came from
  246.                               ;   (i.e., ===>  _chips) carrying the NDP
  247.                               ;   type in Ur AX register
  248. ndp_type       endp
  249.  
  250. _TEXT   ENDS
  251.  
  252. ;
  253. ; The following lines are required for TurboC 2.0:
  254. ;
  255.  
  256. DGROUP  GROUP _DATA
  257.  
  258. _DATA   SEGMENT WORD PUBLIC 'DATA'
  259. _DATA   ENDS
  260.  
  261.         END
  262.