home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Masterblend / cdsharewaremasterblend.iso / utils / infoplus / infoplus.asm < prev    next >
Assembly Source File  |  1990-12-08  |  31KB  |  993 lines

  1. ;--------------------------------------------------------------------
  2. ;
  3. ;       INFOPLUS.ASM
  4. ;
  5. ;       Version 1.41
  6. ;
  7. ;       Ten subprograms used by INFOPLUS.PAS:
  8. ;
  9. ;               CPUID           - identifies host CPU and NDP (if
  10. ;                                       any)
  11. ;               DISKREAD        - reads absolute sectors from disk
  12. ;               LONGCALL        - calls a routine using a CALL FAR
  13. ;               ATIINFO         - for accessing ATI VGAWonder cards
  14. ;               ALTINTR         - calls interrupts with a true INT call
  15. ;               ALTMSDOS        - calls DOS with a true INT call
  16. ;               CIRRUSCK        - Cirrus VGA check
  17. ;               CTICK           - Chips & Technologies VGA check
  18. ;               TSENGCK         - Tseng VGA check
  19. ;               ZYMOSCK         - ZyMOS VGA check
  20. ;
  21. ;       Originally by:
  22. ;       Steve Grant
  23. ;       Long Beach, CA
  24. ;       January 13, 1989
  25. ;
  26. ;       mods by Andrew Rossmann (12/8/90)
  27. ;--------------------------------------------------------------------
  28.  
  29. .286P
  30. .8087
  31.  
  32.         public  CPUID, DISKREAD, LONGCALL, ATIINFO, ALTINTR, ALTMSDOS
  33.         public  CTICK, TSENGCK, ZYMOSCK, CIRRUSCK
  34.  
  35. CODE    segment byte
  36.  
  37. ;       Conditional jumps are all coded with the SHORT qualifier in
  38. ;       order to minimize the size of the .OBJ file output of Turbo
  39. ;       Assembler.
  40.  
  41. ;--------------------------------------------------------------------
  42.  
  43. CPUID   proc    far
  44.  
  45. assume  cs:CODE, ds:DATA, es:nothing, ss:nothing
  46.  
  47. ;       On entry:
  48. ;
  49. ;               BP
  50. ;       SP =>   near return address
  51. ;               offset  of a cpu_info_t record
  52. ;               segment "  "     "        "
  53. ;       also, the test type byte should be a 'C' or 'N' to execute the
  54. ;       CPU or NDP tests.
  55. ;
  56. ;       On exit, the cpu_info_t record has been filled in as follows:
  57. ;
  58. ;               byte    = CPU type
  59. ;               word    = Machine Status Word
  60. ;               6 bytes = Global Descriptor Table
  61. ;               6 bytes = Interrupt Descriptor Table
  62. ;               boolean = segment register change/interrupt flag
  63. ;               byte    = NDP type
  64. ;               word    = NDP control word
  65. ;               byte    = Weitek presence
  66. ;               byte    = test type (C, N, or W)
  67.  
  68. cpu_info        equ     [bp + 6]
  69.  
  70. mCPU    equ     byte ptr [bx]
  71. mMSW    equ     word ptr [bx + 1]
  72. mGDT    equ     [bx + 3]
  73. mIDT    equ     [bx + 9]
  74. mchkint equ     byte ptr [bx + 15]
  75. mNDP    equ     byte ptr [bx + 16]
  76. mNDPCW  equ     word ptr [bx + 17]
  77. mWeitek equ     byte ptr [bx + 19]
  78. mtest   equ     byte ptr [bx + 20]
  79.  
  80. f8088   equ     0
  81. f8086   equ     1
  82. fV20    equ     2
  83. fV30    equ     3
  84. f80188  equ     4
  85. f80186  equ     5
  86. f80286  equ     6
  87. f80386  equ     7
  88. f80486  equ     8
  89. funk    =       0FFH
  90.  
  91. false   equ     0
  92. true    equ     1
  93.  
  94.         push    bp
  95.         mov     bp,sp
  96.         push    ds
  97.         lds     bx,cpu_info
  98.         cmp     mtest, 'C'
  99.         jnz     skipcpu
  100.         call    cpu
  101.         call    chkint
  102. skipcpu:
  103.         cmp     mtest, 'N'
  104.         jnz     skipndp
  105.         call    ndp
  106. skipndp:
  107.         cmp     mtest, 'W'
  108.         jnz     skipweitek
  109.         call    weitek
  110. skipweitek:
  111.         pop     ds
  112.         pop     bp
  113.         ret     4
  114. CPUID   endp
  115.  
  116. ;--------------------------------------------------------------------
  117.  
  118. cpu     proc    near
  119.  
  120. ; interrupt of multi-prefix string instruction
  121.  
  122.         mov     mCPU,funk               ;set CPU type to unknown
  123.         sti
  124.         mov     cx,0FFFFH
  125. rep     lods    byte ptr es:[si]
  126.         jcxz    short cpu_02
  127.         call    piq
  128.         cmp     dx,4
  129.         jg      short cpu_01
  130.         mov     mCPU,f8088
  131.         jmp     cpu_done
  132. cpu_01:
  133.         cmp     dx,6
  134.         jne     cpu_01a
  135.         mov     mCPU,f8086
  136. cpu_01a:
  137.         jmp     cpu_done
  138. cpu_02:
  139.  
  140. ; number of bits in displacement register used by shift
  141.  
  142.         mov     al,0FFH
  143.         mov     cl,20H
  144.         shl     al,cl
  145.         or      al,al
  146.         jnz     short cpu_04
  147.         call    piq
  148.         cmp     dx,4
  149.         jg      short cpu_03
  150.         mov     mCPU,fV20
  151.         jmp     cpu_done
  152. cpu_03:
  153.         cmp     dx,6
  154.         je      cpu_03a
  155.         jmp     cpu_done
  156. cpu_03a:
  157.         mov     mCPU,fV30
  158.         jmp     cpu_done
  159. cpu_04:
  160.  
  161. ; order of write/decrement by PUSH SP
  162.  
  163.         push    sp
  164.         pop     ax
  165.         cmp     ax,sp
  166.         je      short cpu_06
  167.         call    piq
  168.         cmp     dx,4
  169.         jg      short cpu_05
  170.         mov     mCPU,f80188
  171.         jmp     cpu_done
  172. cpu_05:
  173.         cmp     dx,6
  174.         jne     short cpu_done
  175.         mov     mCPU,f80186
  176.         jmp     cpu_done
  177.  
  178. ; We most likely have a 286, 386 or 486 CPU by now
  179. ;First, grab some tables
  180.  
  181. cpu_06:
  182.         smsw    mMSW
  183.         sgdt    mGDT
  184.         sidt    mIDT
  185.  
  186. ;!!!!!!!
  187. ;!!! Original 286/386 detection code (modified 8/10/90)
  188. ;!!! Modified by code supplied by John Levine, apparantly from an Intel
  189. ;!!! '486 manual.
  190. ;!!!!!!!
  191.  
  192.         pushf                           ;put flags into CX
  193.         pop     cx
  194.         and     cx,0fffh                ;mask off upper 4 bits
  195.         push    cx
  196.         popf
  197.         pushf
  198.         pop     ax
  199.         and     ax,0f000h               ;look only at upper 4 bits
  200.         cmp     ax,0f000h               ;88/86 etc.. turn them on
  201.         jz      badcpu                  ;not 286/386/486!!!
  202.         or      cx,0f000h               ;force upper 4 bits on
  203.         push    cx
  204.         popf
  205.         pushf
  206.         pop     ax
  207.         and     ax,0f000h
  208.         jz      found286                ;bits are zeroed in real mode 286
  209. ;
  210. ;since we probably have have a 386 or 486 by now, we need to do some 32-bit
  211. ;work. Detect the 486 by seeing if the Alignment Check flag is settable. This
  212. ;flag only exists on the '486.
  213. ;
  214. .386
  215.         and     esp,0FFFFh              ;use only 64K stack
  216.         mov     edx,esp                 ;save current stack position
  217.         and     esp,0FFFCh              ;dword align to avoid traps
  218.         pushfd                          ;push 32 bit flag
  219.         pop     eax
  220.         mov     ecx,eax                 ;save current flags
  221.         xor     eax,40000h              ;flip AC (alignment check) flag
  222.         push    eax
  223.         popfd
  224.         pushfd
  225.         pop     eax
  226.         xor     eax,ecx                 ;eliminate all but AC bit
  227.         push    ecx                     ;restore flags
  228.         popfd
  229.         mov     esp,edx                 ;restore stack position
  230.         test    eax,40000h              ;is bit set?
  231. .286
  232.         jz      found386                ;if not, is a 386
  233.         mov     mCPU,f80486             ;must be a 486!!
  234.         jmp     short cpu_done
  235. found286:
  236.         mov     mCPU,f80286
  237.         jmp     short cpu_done
  238. found386:
  239.         mov     mCPU,f80386
  240.         jmp     short cpu_done
  241. badcpu:
  242.         mov     mCPU,funk               ;how'd an 8088 get this far?????
  243. CPU_done:
  244.         ret
  245. cpu     endp
  246. ;--------------------------------------------------------------------
  247.  
  248. piq     proc    near
  249.  
  250. ;       On exit:
  251. ;
  252. ;               DX      = length of prefetch instruction queue
  253. ;
  254. ;       This subroutine uses self-modifying code, but can
  255. ;       nevertheless be run repeatedly in the course of the calling
  256. ;       program.
  257.  
  258. count   =       7
  259. opincdx equ     42H                     ; inc dx opcode
  260. opnop   equ     90H                     ; nop opcode
  261.  
  262.         mov     al,opincdx
  263.         mov     cx,count
  264.         push    cx
  265.         push    cs
  266.         pop     es
  267.         mov     di,offset piq_01 - 1
  268.         push    di
  269.         std
  270.         rep stosb
  271.         mov     al,opnop
  272.         pop     di
  273.         pop     cx
  274.         xor     dx,dx
  275.         cli
  276.         rep stosb
  277.         rept    count
  278.         inc     dx
  279.         endm
  280. piq_01:
  281.         sti
  282.         ret
  283. piq     endp
  284.  
  285. ;--------------------------------------------------------------------
  286.  
  287. chkint  proc    near
  288.  
  289. ; save old INT 01H vector
  290.  
  291.         push    bx
  292.         mov     ax,3501H
  293.         int     21H
  294.