home *** CD-ROM | disk | FTP | other *** search
- ;
- ; CPU.ASM
- ;
- ; Return CPU type
- ;
- ; 0 = 8086
- ; 1 = 80186
- ; 2 = 80286
- ; 3 = 80386
- ; 4 = 80486
- ;
- INCLUDE rules.asi
-
-
- GETINTR = 035h
- SETINTR = 025h
- UNDEFINTR = 6
- BOUNDINTR = 5
-
- ;MAcro fools the assembler by not creating an END statement until needed
- ENDEXP MACRO Sym,E
- E&NDIF ; First close the IF
- E&ND Sym ; Now END
- ENDM
-
- .386p
- Code_Seg@
- assume ds:nothing, es:nothing, ss:nothing
- ifdef STANDALONE
- org 100h ; for TINY version
- endif
- PubProc@ CpuType,c
- link@ si
- sub si,si ; CPU type = 8086
- mov al,BOUNDINTR ; See if BOUND instr failes
- mov cx, offset Isbound
- call Taken
- jc found ; not taken, 8086
- inc si ; assume 80186
- mov ax, 0ffffh ; init AX and flags
- clc ; This will guarantee AX to change
- ; if the SMSW succeeds
- cli
- mov cx,sp ; Clear stack pointer
- sub sp,sp
- smsw ax ; If this 286 instruction fails
- ; It will look like an ADD AX,SP
- ; to the 8086
- mov sp,cx ; Restore stack pointer
- sti
- inc ax
- jz found
- inc si ; assume 80286
- mov al, UNDEFINTR
- mov cx, offset Undef
- call Taken
- jc found ; not taken,80286
- inc si ; assume 80386
- mov edx,esp
- and ah,-4
- pushfd
- cli
- pop eax
- mov ecx,eax
- xor eax,40000h
- push eax
- popfd
- pushfd
- pop eax
- xor eax,ecx
- shr eax,12h
- and al,+1
- push ecx
- popfd
- mov esp,edx
- or al,al
- jz found
- inc si ; 80486
- found:
- mov ax,si
- unLink@ si
- ifdef STANDALONE
- push ax
- mov dx,offset msg1
- mov ah,9
- MSDOS@
- pop ax
- or al,al
- jz domsg2
- mov dl,al ; Tiny version, display results
- add dl,'0'
- mov ah,2
- MSDOS@
- domsg2:
- mov dx,offset msg2
- mov ah,9
- MSDOS@
- mov al,0 ; and exit
- mov ah,4ch
- MSDOS@
- endif
- ret
-
- EndProc@ CpuType,c
- msg1 db "CPU type: 80$"
- msg2 db "86$"
- Taken PROC NEAR
- push ds ; Save segs
- push es
- mov ah, GETINTR ; Get old value of interrupt
- MSDOS@
- push cs ; Make our own
- pop ds
- mov dx, offset istaken
- mov ah, SETINTR
- MSDOS@
- call cx ; Call the routine
- stc ; Failed, set carry
- jmp clearint
- istaken:
- ; IF we got here the interrupt was taken
- pop cx ; Clear stack of INTR params
- pop cx
- pop cx
- pop cx ; And the subroutine return
- clc ; Success, clear carry
- clearint:
- pushf
- push es ; Restore the interrupt
- pop ds
- mov dx,bx
- mov ah, SETINTR
- MSDOS@
- popf
- pop es ; Restore segment regs
- pop ds
- ret
- Taken ENDP
- bounds dw 5,10
- Isbound PROC NEAR
- sub cx,cx ; Set us out of bounds
- bound cx,dword ptr [bounds] ; Check bounds
- db 0c9h ; MODRM cx,cx, in case this fails
- ; we want to have no adverse affects
- ; on an 8086; failure will look like
- ; PUSH CS; ADD CX,CX
- pop cx ; So clear the stack
- ret
- Isbound ENDP
- Undef PROC NEAR
- db 00fh ; Undefined 2 byte 386 opcode
- clc ; So we don't affect anything if 286
- ret
- Undef ENDP
-
-
- Code_EndS@
- ifdef STANDALONE
- ENDEXP CpuType@,E
- else
- ENDEXP ,E
- endif