⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_type.ash

📁 CPU特性检测程序源代码 1.17。VB编写的对于系统编程感兴趣的朋友
💻 ASH
📖 第 1 页 / 共 3 页
字号:
ifdef	__386STEP__

stepB0	EQU	0
stepB1	EQU	1
stepD0	EQU	2

ifdef	__PRINT_STEP__

stepTable	label	word
	dw	offset B0Str
	dw	offset B1Str
	dw	offset D0Str

Lstring	B0Str,<B0 or earlier>
Lstring B1Str,<B1>
Lstring D0Str,<D0 or later>
Lstring stepStr,<, chip step is >

print_Step	proc
	.8086
	ldx	stepStr
	call	WriteStr
	call	i386step
	mov	bl,al
	clr	bh
	shl	bx,1
	mov	dx,stepTable[bx]
	call	WriteStr
	ret
	endp

endif

; this routine determines 386DX chip stepping.
; ripped from Phar Lap TellMe utility.

; returns:
;		ax = 0  ->  chip is step B0 or earlier
;		ax = 1	->  chip is step B1
;		ax = 2  ->  chip is step D0 or later

i386step	proc
	.386
	push	bx cx dx si di es ds
	mov	ax,3506h
	int	21h
	push	cs
	pop	ds
	mov	dx,offset @@int06h
	mov	ax,2506h
	int	21h
	clr	cx
	inc	cx
;	.486
;	cmpxchg	ds:[bx+si],al	; this command sequence cause INT 06
	db	0Fh,0A6h,00h	; to occur on 386s later than step B0.

				; TASM does not generate this code when
				; using mnemonics. Generated code 
				; differs from that specified in db
				; but decodes in the same instruction.
@@B0:
	mov	dx,bx
	push	es
	pop	ds
	mov	ax,2506h
	int	21h
	jcxz	@@checkB1
	clr	ax
	jmp	@@Qstep
@@int06h:
	clr	cx
	add	sp,4
	popf
	jmp	@@B0
@@buf	dw	0
@@checkB1:
	mov	di,offset @@buf
	mov	dx,80h
	inc	cx		; cx = 0 if we got here
	mov	ax,cx
	inc	ax
	cld
	push	ax
	rep	insb		; repeating insb 1 times on B1 step chip does
				; not reset cx to zero.
	pop	ax
	jcxz	@@Qstep
	dec	ax
@@Qstep:
	pop	ds es di si dx cx bx
	ret
	endp

endif

ifdef	__PRINT_FPU__

FPUs	dw	offset fpuUnknown	; ?
	dw	offset fpuUnknown	; ?
	dw	offset fpuNone		; ---
	dw	offset fpuWeitek	; Weitek
	dw	offset fpu87		; 8087
	dw	offset fpu87W		; 8087 + Weitek
	dw	offset fpu487sx		; i487sx
	dw	offset fpu487sxw	; i487sx + Weitek
	dw	offset fpu287		; 80287
	dw	offset fpu287W		; 80287 + Weitek
	dw	offset fpu2C87		; Cyrix 2C87
	dw	offset fpu2C87W		; Cyrix 2C87 + Weitek
	dw	offset fpu387		; 80387
	dw	offset fpu387W		; 80387 + Weitek
	dw	offset fpu3C87		; Cyrix 3C87
	dw	offset fpu3C87W		; Cyrix 3C87 + Weitek
	dw	offset fpuBuiltIn	; 486 internal
	dw	offset fpuBuiltInW	; 486 internal + Weitek
	dw	offset fpu4C87		; Cyrix 4C87
	dw	offset fpu4C87W		; Cyrix 4C87 + Weitek
	dw	offset fpu287XL		; Intel 80287XL
	dw	offset fpu287XLW	; Intel 80287XL + Weitek
	dw	offset fpuIIT2C87	; IIT 2C87
	dw	offset fpuIIT2C87W	; IIT 2C87 + Weitek
	dw	offset fpuIIT3C87	; IIT 3C87
	dw	offset fpuIIT3C87W	; IIT 3C87 + Weitek
	dw	offset fpuULSI83C87	; ULSI 83C87
	dw	offset fpuULSI83C87W	; ULSI 83C87 + Weitek
	dw	offset fpuEMC87		; Intel EMC87
	dw	offset fpuEMC87W	; Intel EMC87 + Weitek
	dw	offset fpuCT		; C&T 38700
	dw	offset fpuCTW		; C&T 38700 + Weitek
	dw	offset Nx587		; NexGen Nx587
	dw	offset Nx587W		; NexGen Nx587 + Weitek
	dw	offset fpuIIT4C87	; IIT 4C87
	dw	offset fpuIIT4C87W	; IIT 4C87 + Weitek

Lstring SLEnhanced,<  [SL Enhanced]>
Lstring FPUis,<Coprocessor: >
Lstring fpuWeitek,<Weitek>
Lstring fpuUnknown,<Unknown>
Lstring fpuNone,<None>
Lstring fpuBuiltIn,<Internal>
Lstring fpu87,<Intel 8087>
Lstring fpu287,<Intel 80287>
Lstring fpu287XL,<Intel 80287XL>
Lstring fpu387,<Intel 80387>
Lstring fpu487sx,<Intel i487sx>
Lstring fpu2C87,<Cyrix 82x87>
Lstring fpu3C87,<Cyrix 83x87>
Lstring fpu4C87,<Cyrix 84x87>
Lstring fpuULSI83C87,<ULSI 83x87>
Lstring fpuEMC87,<Cyrix EMC87>
Lstring fpuCT,<C&T 38700>
Lstring fpuIIT2C87,<IIT 2C87>
Lstring fpuIIT3C87,<IIT 3C87>
Lstring fpuIIT4C87,<IIT 4C87>
Lstring Nx587,<NexGen Nx587>
Lstring fpu487sxw,<Intel i487sx and Weitek>
Lstring fpuBuiltInW,<Internal and Weitek>
Lstring fpu87W,<Intel 8087 and Weitek>
Lstring fpu287W,<Intel 80287 and Weitek>
Lstring fpu287XLW,<Intel 80287XL and Weitek>
Lstring fpuIIT2C87W,<IIT 2C87 and Weitek>
Lstring fpuIIT3C87W,<IIT 3C87 and Weitek>
Lstring fpuIIT4C87W,<IIT 4C87 and Weitek>
Lstring fpu387W,<Intel 80387 and Weitek>
Lstring fpu2C87W,<Cyrix 2C87 and Weitek>
Lstring fpu3C87W,<Cyrix 3C87 and Weitek>
Lstring fpu4C87W,<Cyrix 4C87 and Weitek>
Lstring fpuULSI83C87W,<ULSI 83x87 and Weitek>
Lstring fpuEMC87W,<Cyrix EMC87 and Weitek>
Lstring fpuCTW,<C&T 38700 and Weitek>
Lstring Nx587W,<NexGen Nx587 and Weitek>
Lstring EndLine,<>,CrLf
Lstring Emulator,<, Emulated>

print_FPU	proc
	ldx	FPUis
	call	WriteStr
	mov	bx,FPUType
	shl	bx,1
	mov	dx,FPUs[bx]
	call	WriteStr
	cmp	al,cpu286
	jb	@@1p
	call	checkEmu
	jnc	@@1p
	ldx	Emulator
	call	WriteStr
@@1p:
	ret
	endp
endif

	.386p

IF ??version LT 400h

rdmsr	macro	Reg			; new 486 and Pentium instruction
	mov	ecx,Reg			; read MSR #ECX into EDX:EAX
	db	0Fh,32h
	endm
wrmsr	macro	Reg			; new 486 and Pentium instruction
	mov	ecx,Reg			; write MSR #ECX from EDX:EAX
	db	0Fh,30h
	endm

ENDIF

checkIBMmsrs	proc	near
; we'll get here only on 386 with CPUID support
; returns CF=1 if IBM MSRs found and sets BL in this case
	push	dx
	smsw	ax
	test	al,1		; we can only do this nasty code in real mode...
	jnz	@@Qs1

;	jz	@@OkWRMSR
;	call	checkQEMM	; ...or under QEMM 7.04 and up. ???
;	jnc	@@Qs1
;@@OkWRMSR:

	push	bx
	push	ds
	mov	ax,350Dh
	int	21h
	push	es
	push	bx
	push	cs
	pop	ds
	mov	dx,offset @@trap0D
	mov	ax,250Dh	; intercept GPF exception
	int	21h
	mov	ax,3506h
	int	21h
	push	es
	push	bx
	mov	dx,offset @@trap06
	mov	ax,2506h	; and Invalid Instruction exception
	int	21h
IF ??version LT 400h
	rdmsr	1000h
ELSE
	mov	ecx,1000h
	.586p
	rdmsr
ENDIF				; We'll get Exception 13 if this MSR is not
	stc			; valid or Exception 06 if this is not IBM386.
	mov	bl,ibm3slc	; IBM 386SLC
	jmp	@@Qs
@@trap06:
	add	sp,4
	popf
	clc
	jmp	@@Qs
@@trap0D:
	add	sp,4
	popf
	clc
@@Qs:
	pop	dx
	pop	ds
	pushf
	mov	ax,2506h
	int	21h
	popf
	pop	dx
	pop	ds
	pushf
	mov	ax,250Dh
	int	21h
	popf
	pop	ds
	pop	bx
@@Qs1:
	pop	dx
	ret
	endp

checkIBMmsrs2	proc	near
; we'll get here only on 486 with CPUID support
	push	dx
	call	checkIBMmsrs	; first check if this is IBM 486SLC chip
	jnc	@@Qi
	push	bx
	push	ds
	mov	ax,350Dh	; we don't need to intercept Exception #6 here,
	int	21h		; for it is proved that RDMSR instruction is
	push	es		; valid for current CPU. But the register we're
	push	bx		; trying to read may be invalid...
	push	cs
	pop	ds
	mov	dx,offset @@trap0D2
	mov	ax,250Dh
	int	21h
IF ??version LT 400h
	rdmsr	1002h		; try to read 486SLC2 specific MSR
ELSE
	mov	ecx,1002h
	.586p
	rdmsr
ENDIF
	mov	bl,ibm4slc2	; IBM 486SLC2
	jmp	@@Qi2
@@trap0D2:
	add	sp,4
	popf
	stc
	mov	bl,ibm4slc	; IBM 486SLC
@@Qi2:
	pop	dx
	pop	ds
	pushf
	mov	ax,250Dh
	int	21h
	popf
	pop	bx
@@Qi:
	pop	dx
	ret
	endp

checkIBMmsrs3	proc	near
; we'll get here only on 486 with CPUID support
	push	dx
	call	checkIBMmsrs2
	jnc	@@Qi4
	push	bx
	push	ds
	mov	ax,350Dh	; we don't need to intercept Exception #6 here,
	int	21h		; for it is proved that RDMSR instruction is
	push	es		; valid for current CPU. But the register we're
	push	bx		; trying to read may be invalid...
	push	cs
	pop	ds
	mov	dx,offset @@trap0D3
	mov	ax,250Dh
	int	21h
IF ??version LT 400h
	rdmsr	1004h		; try to read 486BL3 specific MSR
ELSE
	mov	ecx,1004h
	.586p
	rdmsr
ENDIF
	mov	bl,ibm4bl3
	jmp	@@Qi3
@@trap0D3:
	add	sp,4
	popf
	stc
@@Qi3:
	pop	dx
	pop	ds
	pushf
	mov	ax,250Dh
	int	21h
	popf
	pop	bx
@@Qi4:
	pop	dx
	ret
	endp


;getQEMMAPI	proc	near
;; get QEMM API entry point
;; returns CF=1 if QEMM found and API entry point got OK.
;	ldx	QEMMId
;	mov	ax,3D00h
;	clr	cx
;	int	21h
;	jc	@@Qa
;	mov	bx,ax
;	mov	ax,4402h
;	mov	cx,4
;	ldx	QEMMEntry
;	int	21h
;	mov	ah,3Eh
;	int	21h
;	clc
;@@Qa:
;	ret
;	endp
;
;checkQEMM	proc	near
;; get and check QEMM version. Only QEMM v7.04 and up enables WRMSR from V86.
;; returns CF=1 if QEMM found and version is OK.
;	push	bx
;	call	getQEMMAPI
;	jc	@@tooearly
;	mov	ah,3
;	call	dword ptr ds:QEMMEntry
;	cmp	bx,0704h
;	pop	bx
;	jb	@@tooearly
;	stc
;	ret
;@@tooearly:
;	clc
;	ret
;	endp
;
;QEMMEntry	dd	?
;QEMMId		db	'QEMM386$',0

	.386

read_chipset	macro
; macro for reading chipset register specified in AL
	out	22h,al
	in	al,23h
	endm

write_chipset	macro
; macro for writing a value in AH to chipset register specified in AL 
	out	22h,al
	mov	al,ah
	out	23h,al
	endm

getCyrixModel	proc
	pushf
	cli
	clr	dx
	mov	al,0C2h
	read_chipset
	mov	cl,al
	or	al,4
	mov	bh,al
	mov	ah,al
	mov	al,0C2h
	write_chipset
	mov	al,0C0h
	read_chipset
	mov	al,0C2h
	read_chipset
	or	al,4
	cmp	al,4
	jne	@@4
	mov	al,cl
	and	al,not 4
	mov	ah,al
	mov	al,0C2h
	write_chipset
	mov	al,0C0h
	read_chipset
	mov	al,0C2h
	read_chipset
	and	al,4
	jnz	@@4
	inc	dh
@@4:
	mov	al,0C2h
	mov	ah,cl
	write_chipset
	mov	al,0C3h
	read_chipset
	mov	cl,al
	or	al,2
	mov	bh,al
	mov	ah,al
	mov	al,0C3h
	write_chipset
	mov	al,0C0h
	read_chipset
	mov	al,0C3h
	read_chipset
	or	al,2
	cmp	al,2
	jne	@@5
	mov	al,cl
	and	al,not 2
	mov	ah,al
	mov	al,0C3h
	write_chipset
	mov	al,0C0h
	read_chipset
	mov	al,0C3h
	read_chipset
	and	al,2
	jnz	@@5
	inc	dl
@@5:
	mov	al,0C3h
	mov	ah,cl
	write_chipset
	test	dl,dl
	jz	@@6
	clr	bx
	clr	cx
	mov	al,0FEh
	read_chipset
	mov	bl,al	; bl = DIR0
	mov	al,0FFh
	read_chipset
	mov	bh,al	; bh = DIR1
	jmp	@@7
@@6:
	clr	bx	; unknown Cyrix chip
@@7:
	sti
	mov	ax,bx
	popf
	ret
	endp

int6H:			; INT 6 (invalid instruction) trap hook
	clr	ax
	add	sp,4	; restore stack and jump past offending instruction
	popf
	jmp	Past_invalid

isSMMAble	proc
	push	ds
	mov	ax,3506h	; get current INT 6 vector
	int	21h
	mov	ax,2506h	; hook INT 6
	mov	dx,offset int6H
	push	cs
	pop	ds
	int	21h
	pop	ds
	clr	ax		; AX = 0
	mov	cl,1		; CL = 1
	mov	dl,ds:[bx+si]	; save byte at [bx+si] in dl

;	The following code ( 0F12C1 ) is SMM instruction UMOV AL,CL that moves
;	data from/to main memory nevertheless the processor is in SMM or not.

;	Cyrix chips doesn't generate INT 6 on this instruction. Instead, two
;	bytes 0F12 gets skipped and the next instruction appears to be
;	{rol word ptr [bx+si],0} ( C10000 ).

	db	0Fh
	adc	al,cl
	add 	ds:[bx+si],al
Past_Invalid:
	mov	ds:[bx+si],dl	; restoring possibly damaged data
	push	ds
	push	es
	pop	ds
	mov	dx,bx
	push	ax
	mov	ax,2506h	; restore INT 6 vector
	int	21h
	pop	ax
	pop	ds
	ret
	endp

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -