home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1992 / 03 / 386step.asm next >
Assembly Source File  |  1992-01-14  |  7KB  |  136 lines

  1. ;****************************************************************************
  2. ; 386STEP identifies the stepping level of a 386 chip as B0 or earlier,
  3. ; B1, or D0 or higher.  Thanks to Bob Moote and Richard Smith of Phar Lap
  4. ; Software for their advice and assistance in preparing this code.
  5. ;
  6. ; Copyright (c) 1992 Jeff Prosise
  7. ; First published in PC Magazine, February 11, 1992
  8. ;****************************************************************************
  9.  
  10.                 .386P
  11.  
  12. code            segment para use16 public 'code'
  13.                 assume  cs:code,ds:code
  14.                 org     100h
  15. begin:          jmp     short main
  16.  
  17. msg             db      "Stepping level $"
  18. stepb0          db      "B0 or earlier$"
  19. stepb1          db      "B1$"
  20. stepd0          db      "D0 or higher$"
  21. errmsg          db      "Error: Not a 386$"
  22.  
  23. ;****************************************************************************
  24. ; Procedure MAIN
  25. ;****************************************************************************
  26.  
  27. main            proc    near
  28. ;
  29. ; Make sure this is a 386 or 486 by toggling the nested task (NT) bit.
  30. ;
  31.                 pushf                           ;Push FLAGS
  32.                 pop     ax                      ;Pop FLAGS into AX
  33.                 mov     bx,ax                   ;Copy result to BX
  34.                 and     bx,4000h                ;Zero all but bit 14
  35.                 xor     ax,4000h                ;Toggle bit 14 in AX
  36.                 push    ax                      ;Transfer the result back
  37.                 popf                            ;  to the FLAGS register
  38.                 pushf                           ;Push FLAGS
  39.                 pop     ax                      ;Pop FLAGS into AX again
  40.                 mov     cx,ax                   ;Transfer the result to CX
  41.                 and     cx,4000h                ;Zero all but bit 14 in CX
  42.                 xor     ax,4000h                ;Toggle bit 14 in AX
  43.                 push    ax                      ;Restore FLAGS with the
  44.                 popf                            ;  original NT bit intact
  45.                 cmp     bx,cx                   ;Compare BX and CX
  46.                 jne     short check486          ;Branch if they're not equal
  47.  
  48. cpu_error:      mov     ah,09h                  ;Display error message and
  49.                 mov     dx,offset errmsg        ;  exit
  50.                 int     21h
  51.                 mov     ax,4C01h
  52.                 int     21h
  53. ;
  54. ; Check for a 486 by toggling the alignment check (AC) bit.
  55. ;
  56. check486:       mov     ebx,esp                 ;Save ESP
  57.                 and     esp,0FFFFFFFCh          ;Zero the lower two bits
  58.                 pushfd                          ;Push EFLAGS
  59.                 pop     eax                     ;Pop it into EAX
  60.                 mov     ecx,eax                 ;Copy EFLAGS to ECX
  61.                 and     ecx,40000h              ;Zero all but bit 18
  62.                 xor     eax,40000h              ;Toggle bit 18 in EAX
  63.                 push    eax                     ;Copy the result back to
  64.                 popfd                           ;  the EFLAGS register
  65.                 pushfd                          ;Push EFLAGS
  66.                 pop     eax                     ;Pop EFLAGS into EAX again
  67.                 mov     ebx,eax                 ;Transfer the result to EBX
  68.                 and     ebx,40000h              ;Zero all but bit 18 in EBX
  69.                 xor     eax,40000h              ;Toggle bit 18 in EAX
  70.                 push    eax                     ;Restore EFLAGS with the
  71.                 popfd                           ;  original AC bit intact
  72.                 mov     esp,ebx                 ;Restore ESP
  73.                 cmp     ebx,ecx                 ;Compare EBX and ECX
  74.                 jne     cpu_error               ;Error if they're not equal
  75.  
  76. is386:          mov     ah,09h                  ;Print "Stepping level"
  77.                 mov     dx,offset msg
  78.                 int     21h
  79. ;
  80. ; Test for a stepping level of B0 or earlier by executing an XBTS instruction
  81. ; and trapping invalid opcode exceptions.
  82. ;
  83.                 mov     ax,3506h                ;Get interrupt 06h vector
  84.                 int     21h                     ;  in ES:BX
  85.                 mov     ax,2506h                ;Point interrupt 06h to
  86.                 mov     dx,offset invalid_op    ;  internal address
  87.                 int     21h
  88.                 mov     dx,0                    ;Set DX to 0
  89.                 mov     cx,1                    ;Initialize CX for XBTS
  90.                 db      0Fh,0A6h,00h            ;Execute XBTS (Step B1 or
  91.                                                 ;  later will branch to
  92.                                                 ;  label INVALID_OP)
  93.                 mov     dx,1                    ;Set DX to 1
  94. invalid_op:     push    ds                      ;Save DS on the stack
  95.                 push    dx                      ;Save DX also
  96.                 mov     dx,bx                   ;Restore the original
  97.                 mov     ax,es                   ;  interrupt 06h vector
  98.                 mov     ds,ax
  99.                 mov     ax,2506h
  100.                 int     21h
  101.                 pop     dx                      ;Restore DX and DS
  102.                 pop     ds
  103.                 or      dx,dx                   ;Branch if DX is still set
  104.                 jz      b1                      ;  to 0
  105.                 mov     dx,offset stepb0        ;Load DX with message pointer
  106.                 jmp     short exit              ;  and exit if it's not
  107. ;
  108. ; Test for stepping level B1 chips by seeing if ECX is properly decremented
  109. ; after a REP INSB instruction followed by a POP.
  110. ;
  111. b1:             cld                             ;Clear direction flag
  112.                 mov     ax,cs                   ;Point ES:EDI to scratch
  113.                 mov     es,ax                   ;  buffer
  114.                 mov     edi,offset msg
  115.                 mov     dx,80h                  ;Load I/O port address
  116.                 mov     ecx,1                   ;Initialize ECX
  117.                 push    ax                      ;Push AX onto the stack
  118.                 rep     insb                    ;Read string from I/O port
  119.                 pop     ax                      ;Pop AX off the stack
  120.                 or      ecx,ecx                 ;Branch if ECX is equal to 0
  121.                 jz      d0
  122.                 mov     dx,offset stepb1        ;Load DX with message pointer
  123.                 jmp     short exit              ;Jump to exit
  124. ;
  125. ; By process of elimination, the chip must be step D0 or higher.
  126. ;
  127. d0:             mov     dx,offset stepd0        ;Load DX with message pointer
  128. exit:           mov     ah,09h                  ;Output string identifying
  129.                 int     21h                     ;  the stepping level
  130.                 mov     ax,4C00h                ;Exit
  131.                 int     21h
  132. main            endp
  133.  
  134. code            ends
  135.                 end     begin
  136.