home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
pcmagazi
/
1992
/
03
/
386step.asm
next >
Wrap
Assembly Source File
|
1992-01-14
|
7KB
|
136 lines
;****************************************************************************
; 386STEP identifies the stepping level of a 386 chip as B0 or earlier,
; B1, or D0 or higher. Thanks to Bob Moote and Richard Smith of Phar Lap
; Software for their advice and assistance in preparing this code.
;
; Copyright (c) 1992 Jeff Prosise
; First published in PC Magazine, February 11, 1992
;****************************************************************************
.386P
code segment para use16 public 'code'
assume cs:code,ds:code
org 100h
begin: jmp short main
msg db "Stepping level $"
stepb0 db "B0 or earlier$"
stepb1 db "B1$"
stepd0 db "D0 or higher$"
errmsg db "Error: Not a 386$"
;****************************************************************************
; Procedure MAIN
;****************************************************************************
main proc near
;
; Make sure this is a 386 or 486 by toggling the nested task (NT) bit.
;
pushf ;Push FLAGS
pop ax ;Pop FLAGS into AX
mov bx,ax ;Copy result to BX
and bx,4000h ;Zero all but bit 14
xor ax,4000h ;Toggle bit 14 in AX
push ax ;Transfer the result back
popf ; to the FLAGS register
pushf ;Push FLAGS
pop ax ;Pop FLAGS into AX again
mov cx,ax ;Transfer the result to CX
and cx,4000h ;Zero all but bit 14 in CX
xor ax,4000h ;Toggle bit 14 in AX
push ax ;Restore FLAGS with the
popf ; original NT bit intact
cmp bx,cx ;Compare BX and CX
jne short check486 ;Branch if they're not equal
cpu_error: mov ah,09h ;Display error message and
mov dx,offset errmsg ; exit
int 21h
mov ax,4C01h
int 21h
;
; Check for a 486 by toggling the alignment check (AC) bit.
;
check486: mov ebx,esp ;Save ESP
and esp,0FFFFFFFCh ;Zero the lower two bits
pushfd ;Push EFLAGS
pop eax ;Pop it into EAX
mov ecx,eax ;Copy EFLAGS to ECX
and ecx,40000h ;Zero all but bit 18
xor eax,40000h ;Toggle bit 18 in EAX
push eax ;Copy the result back to
popfd ; the EFLAGS register
pushfd ;Push EFLAGS
pop eax ;Pop EFLAGS into EAX again
mov ebx,eax ;Transfer the result to EBX
and ebx,40000h ;Zero all but bit 18 in EBX
xor eax,40000h ;Toggle bit 18 in EAX
push eax ;Restore EFLAGS with the
popfd ; original AC bit intact
mov esp,ebx ;Restore ESP
cmp ebx,ecx ;Compare EBX and ECX
jne cpu_error ;Error if they're not equal
is386: mov ah,09h ;Print "Stepping level"
mov dx,offset msg
int 21h
;
; Test for a stepping level of B0 or earlier by executing an XBTS instruction
; and trapping invalid opcode exceptions.
;
mov ax,3506h ;Get interrupt 06h vector
int 21h ; in ES:BX
mov ax,2506h ;Point interrupt 06h to
mov dx,offset invalid_op ; internal address
int 21h
mov dx,0 ;Set DX to 0
mov cx,1 ;Initialize CX for XBTS
db 0Fh,0A6h,00h ;Execute XBTS (Step B1 or
; later will branch to
; label INVALID_OP)
mov dx,1 ;Set DX to 1
invalid_op: push ds ;Save DS on the stack
push dx ;Save DX also
mov dx,bx ;Restore the original
mov ax,es ; interrupt 06h vector
mov ds,ax
mov ax,2506h
int 21h
pop dx ;Restore DX and DS
pop ds
or dx,dx ;Branch if DX is still set
jz b1 ; to 0
mov dx,offset stepb0 ;Load DX with message pointer
jmp short exit ; and exit if it's not
;
; Test for stepping level B1 chips by seeing if ECX is properly decremented
; after a REP INSB instruction followed by a POP.
;
b1: cld ;Clear direction flag
mov ax,cs ;Point ES:EDI to scratch
mov es,ax ; buffer
mov edi,offset msg
mov dx,80h ;Load I/O port address
mov ecx,1 ;Initialize ECX
push ax ;Push AX onto the stack
rep insb ;Read string from I/O port
pop ax ;Pop AX off the stack
or ecx,ecx ;Branch if ECX is equal to 0
jz d0
mov dx,offset stepb1 ;Load DX with message pointer
jmp short exit ;Jump to exit
;
; By process of elimination, the chip must be step D0 or higher.
;
d0: mov dx,offset stepd0 ;Load DX with message pointer
exit: mov ah,09h ;Output string identifying
int 21h ; the stepping level
mov ax,4C00h ;Exit
int 21h
main endp
code ends
end begin