; 	[]===========================================================[]
;
;	NOTICE: THIS PROGRAM BELONGS TO AWARD SOFTWARE INTERNATIONAL(R)
;	        INC. IT IS CONSIDERED A TRADE SECRET AND IS NOT TO BE
;	        DIVULGED OR USED BY PARTIES WHO HAVE NOT RECEIVED
;	        WRITTEN AUTHORIZATION FROM THE OWNER.
;
; 	[]===========================================================[]
;
;----------------------------------------------------------------------------
;Rev  	Date	 Name	Description
;----------------------------------------------------------------------------
;R00	03/15/99 RAY	Initial revision in which the code is extracted from
;			the original CPUPOST.ASM. To prevent compilation error
;			Please define "NO_586_SUPPORT" in your BIOS.CFG

IF	COMPILE_FOR_E0
IF	STR_function	EQ	1
		extrn	CT_OPEN_SM_RAM:near
		extrn	CT_CLOSE_SM_RAM:near
		extrn	Get_SMBASE_ADD:near
ENDIF	;STR_function	EQ	1

 ifdef	L2ECC_CMOS
		extrn	L2Ecc_Item:near
 endif;	L2ECC_CMOS

		extrn	POST_decompress:near
		extrn	F000_GetItem_Value:near
		extrn	ExtCache_Item:near

		EXTRN	ROM_AND_CMOS:NEAR
		EXTRN	ROM_OR_CMOS:NEAR
		extrn	POST_func_end:Near
		extrn	POST_VECT:Near

		extrn	Check_Cyrix_Cpu:near
		extrn	Init_Cyrix_Reg:near
		extrn	Get_Cmos:near
		extrn	Set_Cmos:near
		extrn	F000_call_proc:near
		extrn	F000_Shadow_W:Near
		extrn	F000_Shadow_R:Near

		extrn	LOCK_CYRIX:Near
		extrn	UNLOCK_CYRIX:Near
		extrn	LOCK_CYRIX:Near
		extrn	SET_CYRIX:Near
		extrn	GET_CYRIX:Near
;;;;;		extrn	Check_M1_Cpu:near
		extrn	F000_Get_Cmos:near
		extrn	F000_Set_Cmos:near

ifdef	ESCD_SUPPORT
ifndef	ESCD_M2
IF BUS_TYPE NE EISA_BUS
		extrn	P5_BtB_Loc:near
endif; BUS_TYPE NE EISA_BUS
endif;	ESCD_M2
endif;	ESCD_SUPPORT

		extrn	Cpu_Cache:near

ifdef	Special_CPU_Clock_Table
		extrn	Ct_Int_Clock_Tbl:Near
endif	;Special_CPU_Clock_Table

.LIST

EGROUP		GROUP	ECODE
ECODE		SEGMENT USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,DS:EGROUP

;=============================================================================
;FUNC:	CYRIX_INIT
;
;DESC:	Handles the initialization of the CYRIX CPU.
;
;IN:	NONE
;OUT:	NONE
;
;SAVES:	NONE + NO STACK
;
;BY:	Richard Chen
;DATE:	18 May 1992
;=============================================================================
FLAGS_MASK	EQU	08D5H

		public	CYRIX_INIT
CYRIX_INIT	proc	near

;First , Check Intel or Cyrix CPU

		F000_call	Check_Cyrix_Cpu
		jnz	Not_Cy_Cpu
Yes_Cy:

;If cyrix CPU plugged, setup noncacheable region.
		mov	al,CMOS_AWARD_2 NMI_OFF

		call	F000_Get_Cmos

		mov	ah,al
		xor	ah,ah
		and	al,CPU_TYPE_MASK

		cmp	al,TYPE_486DX
		jne	Check_Cyrix_1

		call	Check_Cyrix_Dclk
		jc	Not_486slc2

		mov	ax,CPU_CX486SLC2
		xchg	ah,al
		jmp	Init_Cyrix
Not_486slc2:

		or	ah,TYPE_486SLC + CPUCACHE
		jmp	Check_TI_CPU
Check_Cyrix_1:

		cmp	al,TYPE_486SX
 		jne	Not_Cy_Cpu

	   	or	ah,TYPE_486DLC + CPUCACHE

Check_TI_CPU:
IF	BIOS_SUPPORT_TI_CPU
		push	eax
		mov	eax,200h

		DB	0FH,26H,0E0H		;mov	tr4,eax
		mov	eax,1

		DB	0FH,26H,0E8H		;mov	tr5,eax
		mov	eax,2

		DB	0FH,26H,0E8H		;mov	tr5,eax
		DB	0FH,24H,0E0H		;mov	eax,tr4
		and	eax,200h
		cmp	eax,200h
		pop	eax
		je	Not_TiCpu

Is_TI486SXL:
	   	and	ah,CPU_TYPE_MASK
		cmp	ah,TYPE_486DLC
		mov	ax,CPU_TI486SXLC
		jne	@F
		mov	ax,CPU_TI486SXL
@@:
		xchg	ah,al

Not_TiCpu:
ENDIF	;BIOS_SUPPORT_TI_CPU

Init_Cyrix:

		mov	al,CMOS_AWARD_2 NMI_OFF

		call	F000_Set_Cmos

		mov	ah,CMOS_OVERRIDE NMI_OFF
		mov	al,ah

		call	F000_Get_Cmos
		xchg	ah,al
		or	ah,SMICPU shr 8

		call	F000_Set_Cmos

Not_Cy_Cpu:
		F000_call	Init_Cyrix_Reg
		ret

CYRIX_INIT	endp

;Input : none
;Output: carry clear - it's double clock
;	 carry set   - it's not double clock
Check_Cyrix_Dclk	proc	near

		push	ax
		mov	al,CMOS_OVERRIDE NMI_OFF

		call	F000_Get_Cmos
		and	al,NOT 11000000b		;set single clock
		mov	ah,al

		mov	al,0feh
		out	22h,al
		in	al,23h
		cmp	al,1bh	  			;Is DX2?
		je	Yes_Dclk
		cmp	al,02h				;Is 486SLC2
		jne	Not_Dclk
Yes_Dclk:
		or	ax,DOUBLECLOCK+SMICPU
		mov	al,CMOS_OVERRIDE NMI_OFF

		call	F000_Set_Cmos
		pop	ax
		clc
		ret
Not_Dclk:
		mov	al,CMOS_OVERRIDE NMI_OFF

		call	F000_Set_Cmos
		pop	ax
		stc
		ret

Check_Cyrix_Dclk	endp

;[]========================================================================[]
;	Set the IBM CPU's Cacheable region: Bit 32-39 of register 1001h
;	according to the extended memory found!
;[]========================================================================[]
		Public	IBMCPU_Cacheable_Size
IBMCPU_Cacheable_Size	Proc	Near

IF	BIOS_SUPPORT_IBM_CPU
		mov	al,FIXED_DISK_STEP[bp]
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_IBM386SLC
		je	Set_Cacheable_Size
		cmp	al,TYPE_IBM486SLC2
		je	Set_Cacheable_Size
		cmp	al,TYPE_IBM486DLC3
		jne	IBMCPU_Cacheable_Exit

Set_Cacheable_Size:

		mov	ecx,1001h
		RDMSR
		mov	ebx,EXT_MEM_SIZE[bp]
		shr	ebx,6			;in terms of 64k
		and	ebx,0FFh
		and	edx,not 0FFh
		or	edx,ebx
		WRMSR

IBMCPU_Cacheable_Exit:
ENDIF	;BIOS_SUPPORT_IBM_CPU

		ret

IBMCPU_Cacheable_Size	Endp

;[]------------------------------------------------------------------------[]
;[]------------------------------------------------------------------------[]
		Public	Chk_Intel_S_CPU
Chk_Intel_S_CPU	Proc	Near

		push	ds
		pushad

IF	BIOS_SUPPORT_486
;-----------------------------------------------------------------------
;There are 3 versions of AMD DX4 CPU
;	1. CPU ID = DX2	(With AMD SMI)
;	2. CPU ID = Intel's P24C (NO SMI)
;	3. AMD Plus Series
;
;The following algorithm is used to distiquish (2) with Intel's P24C
;	a. if ID <> P24C (i.e. 048X) then skip (b) & (c)
;	b. clear the SMICPU bit
;	c. issue CPUID instruction (which will set SMICPU bit if valid)
;	d. if ID <> P24C (i.e. 048X) then goto (g)
;	e. if SMICPU bit is set then goto
;	f. change CPU type to AMD DX4
;	g. exit
;-----------------------------------------------------------------------
		call	Chk_If_Type_P24C
		jne	@F
		call	Clear_SMI_Bit
	@@:
ENDIF	;BIOS_SUPPORT_486

	;replace the original int 06h with a temparary
	;one to prevent trap accurs in some CPUs

		xor	eax,eax			;input value = 1
		mov	ds,ax

		push	dword ptr ds:[4*6]	;save int 06h vector
		mov	word ptr ds:[4*6],offset Temp_Int06
		mov	word ptr ds:[4*6+2], 0e000h

		push	ds

		push	cs
		pop	ds

	;issue special OP code: CPUID(00Fh,0A2h)
	;to check if it is a S-series CPU

		db	0Fh,0A2h		;OP code: CPUID

		mov	si,offset Cpu_Vendor_Tbl
Chk_Nxt_Vendor:
		cmp	word ptr [si],-1 	;last of CPU vendor table

		je	Finish_Cpu_ID		;yes,over !

		cmp	ebx,[si+2]		;check 1st identifier string
		jne	Next_Vendor

		cmp	ecx,[si+6]		;check 2nd identifier string
		jne	Next_Vendor

		cmp	edx,[si+10]		;check 3th identifier string
		je	Good_Vendor

Next_Vendor:
		add	si,SIZE_VENDOR_TBL
		jmp	Chk_Nxt_Vendor

Good_Vendor:
		call	Set_SMI_Bit

		mov	si,[si]	 		;get vendor's CPU ID table
	;Now , we got correct identifier of CPU, next step is to get CPU ID
		mov	eax,1			;eax = 1 to read CPU ID
		db	0fh,0A2h		;CPU ID instruction
		and	al,0f0h			;mask stepping bits b3-b0

Chk_Nxt_CpuID:
		cmp	word ptr [si],-1 	;last of CPU ID table
		je	Finish_Cpu_ID

		cmp	ax,[si]			;match CPU ID ?
		je	Save_Cpu_ID	;yes

		add	si,4			;next CPU ID
		jmp	Chk_Nxt_CpuID
CpuIdNotFound:
Save_Cpu_ID:
		mov	dx,[si+2]		;get CPU ID
		call	Set_CPU_Type_Bits
		jmp	Finish_Cpu_ID

Finish_Cpu_ID:

		pop	ds

IF	BIOS_SUPPORT_486
;-----------------------------------------------------------------------
;if it is Type P24C without SMICPU bit,
;  then it must be a AMD-DX4 which has the same CPU ID with Intel's P24C
;So, change the CPU type to CPU_AMD486DX4
;-----------------------------------------------------------------------

		call	Chk_If_Type_P24C
		jne	_A_Y_J
		call	Chk_SMICPU_Bit
		jnz	_A_Y_J
		mov	dx,(CPU_AMD486DX4) AND (NOT SMICPU)
		call	Set_CPU_Type_Bits
	_A_Y_J:
ENDIF	;BIOS_SUPPORT_486

		pop	dword ptr ds:[4*6]	;restore int 06h vector

		call	Prepare_CPU_Info
		popad
		pop	ds
		ret

;-------------------------------------------------------
; Temporary Int 06 handler for Non-(Intel S-Series) CPU
;-------------------------------------------------------
		public	Temp_Int06

Temp_Int06	Label	Near
		push	bp
		mov	bp,sp
		add	word ptr ss:[bp+2],2
		pop	bp
		iret

Chk_Intel_S_CPU	Endp

Cpu_Vendor_Tbl:
		dw	offset Cpu_INTELs  	;table of INTEL CPUs
		dd	756E6547h	   	;Identifer string 1
		dd	6C65746eh	   	;Identifer string 2
		dd	49656E69h	   	;Identifer string 3
SIZE_VENDOR_TBL	EQU	$ - offset Cpu_Vendor_Tbl

IF	BIOS_SUPPORT_486
		dw	offset Cpu_UMCs	   	;table of UMC CPUs
		dd	20434d55h	   	;Identifer string 1
		dd	20434d55h	   	;Identifer string 2
		dd	20434d55h	   	;Identifer string 3
ENDIF	;BIOS_SUPPORT_486

		dw	offset Cpu_AMDs	   	;table of AMD CPUs
		dd	68747541h	   	;Identifer string 1
		dd	444d4163h	   	;Identifer string 2
		dd	69746e65h	   	;Identifer string 3

		dw	-1		   	;last of CPU venders table

;CPU table for INTEL s-series CPUs
Cpu_INTELs:
IF	BIOS_SUPPORT_486
		dw	0470h,(CPU_P24D) 		;P24D with WT
		dw	0480h,(CPU_P24C) 		;P24C with WT
		dw	1480h,(CPU_P24C) 		;P24C with ODP
		dw	0490h,(CPU_P24C) OR (WBCPU)	;P24C with WB
		dw	1490h,(CPU_P24C) OR (WBCPU)	;P24C with WB/ODP
		dw	1530h,CPU_P24T			;P24T
ENDIF	;BIOS_SUPPORT_486

		dw	-1				;last of table

		ALIGN	16

;CPU table for AMD s-series CPUs
Cpu_AMDs:
IF	BIOS_SUPPORT_486
		dw	0430h,(CPU_AMD486PLUS) 		;DX2 plus WT
		dw	0470h,(CPU_AMD486WB_PLUS)      	;DX2 plus WB
		dw	0480h,(CPU_AMD486DX4PLUS)	;DX4 plus WT
		dw	0490h,(CPU_AMD486DX4WB_PLUS)	;DX4 plus WB
		dw	04E0h,(CPU_AMDDX5WT)		;DX5 plus WT
		dw	04F0h,(CPU_AMDDX5WB)		;DX5 plus WB
ENDIF	;BIOS_SUPPORT_486
		dw	-1

;CPU table for UMC s-series CPUs
Cpu_UMCs:
IF	BIOS_SUPPORT_486
		dw	0420h,CPU_U5			;486SX
		dw	0450h,CPU_U486SX2		;486SX2
		dw	0410h,CPU_U486DX		;486DX
		dw	0430h,CPU_U486DX2		;486DX2
ENDIF	;BIOS_SUPPORT_486
		dw	-1

;;;;;Cpu_IDTs:	;table of IDT CPUs
;;;;;		dw	0520h,CPU_586			;C6 w/o MMX
;;;;;		dw	0540h,CPU_586			;C6 w/  MMX
;;;;;		dw	0580h,CPU_586			;WinChip 2
;;;;;		dw	0590h,CPU_586			;WinChip 2
;;;;;		dw	-1
;;;;;
;;;;;;CPU table for Rise s-series CPUs
;;;;;Cpu_Rise:
;;;;;		dw	-1				;last of table

;[]==========================================================[]
;[]==========================================================[]
		Public	Chk_If_Type_P24C
Chk_If_Type_P24C:
IF	BIOS_SUPPORT_486
		push	ax
		mov	al,CMOS_AWARD_2 NMI_OFF

		call	F000_Get_Cmos
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_P24C
		pop	ax
ENDIF	;BIOS_SUPPORT_486
		ret

;[]==========================================================[]
;[]==========================================================[]
		Public	Set_SMI_Bit
Set_SMI_Bit:
		mov	ah,CMOS_OVERRIDE NMI_OFF
		mov	al,ah

		call	F000_Get_Cmos
		or	al,SMICPU shr 8
		xchg	ah,al

		call	F000_Set_Cmos
		ret

;[]==========================================================[]
;[]==========================================================[]
		Public	Clear_SMI_Bit
Clear_SMI_Bit:
		mov	ah,CMOS_OVERRIDE NMI_OFF
		mov	al,ah

		call	F000_Get_Cmos
		and	al,NOT (SMICPU shr 8)
		xchg	ah,al

		call	F000_Set_Cmos
		ret

;[]==========================================================[]
;[]==========================================================[]
		Public	Chk_SMICPU_Bit
Chk_SMICPU_Bit:
		push	ax
		mov	al,CMOS_OVERRIDE NMI_OFF

		call	F000_Get_Cmos
		test	al,SMICPU shr 8
		pop	ax
		ret

;[]==========================================================[]
;Input : DL = Value for CMOS_AWARD_2  (03DH)
;        DH = Value for CMOS_OVERRIDE (03FH)
;[]==========================================================[]
Set_CPU_Type_Bits:
		mov	al,CMOS_AWARD_2 NMI_OFF
		mov	ah,dl

		call	F000_Set_Cmos

		mov	ah,CMOS_OVERRIDE NMI_OFF
		mov	al,ah

		call	F000_Get_Cmos
		and	al,NOT (CLOCK_MODE+((SMICPU+WBCPU) SHR 8))
		or	al,dh
		xchg	ah,al

		call	F000_Set_Cmos
		ret

;[]------------------------------------------------------------------------[]
;[]------------------------------------------------------------------------[]
		public	Intel_To_AMD
Intel_To_AMD	proc	near

IF	BIOS_SUPPORT_486
		pusha
		mov	al,CMOS_AWARD_2 NMI_OFF

		call	F000_Get_Cmos
		and	al,CPU_TYPE_MASK
		mov	dx,CPU_AMD486
		cmp	al,TYPE_486DX
		je	@F
		mov	dx,CPU_AMD486DX2
@@:
		call	Set_CPU_Type_Bits

		mov	word ptr CPU_BRAND[bp],((SMI_TYPE_OLD_AMD) shl 8)+(CPU_BRAND_AMD)

		popa
ENDIF	;BIOS_SUPPORT_486

		ret

Intel_To_AMD	endp

;[]------------------------------------------------------------------------[]
;Procedure	:	Prepare_CPU_Info
;
;Input		:	None
;
;Output		:	None
;
;Description	:	- This routine is called after the BIOS has issued
;			  the CPUID instruction & all the CPUs are identified.
;
;			- There are 2 variables in the stack area namely
;			  CPU_BRAND[bp] & CPU_SMI_TYPE[bp]
;			  This routine will place appropriate values into
;			  these 2 [BP] variables
;			  The BIOS engineers can easily reference to them
;			  for their own programming
;
;			- please refer to BSETUP.INC for the definitions
;			  of CPU_BRAND[bp] & CPU_SMI_TYPE[bp]
;
;Note		:	BIOS engineers should use instruction "test" to
;			check SMI type & "cmp" for CPU brand
;
;			e.g.
;			    cmp   CPU_BRAND[bp], CPU_BRAND_CYRIX
;			    test  CPU_SMI_TYPE[bp], SMI_TYPE_CYRIX
;
;[]------------------------------------------------------------------------[]
		Public	Prepare_CPU_Info
Prepare_CPU_Info	Proc	Near

		mov	al,CMOS_AWARD_2 NMI_OFF

		call	F000_Get_Cmos
		and	al,CPU_TYPE_MASK
		movzx	si,al

		xor	ah, ah
		shr	ax, 1
		add	si, ax

		mov	dx,word ptr cs:CPU_Info_Tbl[si]
		mov	word ptr CPU_BRAND[bp],dx

		mov	al, byte ptr cs:CPU_Info_Tbl[si+2]
		mov	byte ptr CPU_LEVEL[bp], al

		mov	al,OVERRIDE NMI_OFF

		call	F000_Get_Cmos
		test	al,((SMICPU) shr 8)		;SMI CPU?
		jnz	Set_SMI_OK		;Yes

		mov	byte ptr CPU_SMI_TYPE[bp],SMI_NONE
Set_SMI_OK:
		ret

Prepare_CPU_Info	Endp

		ALIGN	4
CPU_Info_Tbl:

	db	CPU_BRAND_INTEL	,SMI_NONE	 ,LEVEL_386	;TYPE_386DX
	db	CPU_BRAND_INTEL	,SMI_NONE 	 ,LEVEL_386	;TYPE_386SX
	db	CPU_BRAND_INTEL	,SMI_NONE 	 ,LEVEL_386	;TYPE_386SL
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL  ,LEVEL_486	;TYPE_486DX
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL  ,LEVEL_486	;TYPE_486SX
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_486DX2
	db	CPU_BRAND_CYRIX	,SMI_NONE	 ,LEVEL_386	;TYPE_486SLC
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_386	;TYPE_486DLC
	db	CPU_BRAND_IBM	,SMI_TYPE_IBM	 ,LEVEL_386	;TYPE_IBM386SLC
	db	CPU_BRAND_IBM	,SMI_TYPE_IBM	 ,LEVEL_386	;TYPE_IBM486SLC2
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_P24T
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_CX486S
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_CX486S2
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_586	;TYPE_586
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_486DXS
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_486SXS
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_486DX2S
	db	CPU_BRAND_IBM	,SMI_TYPE_IBM	 ,LEVEL_386	;TYPE_IBM486DLC3
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_M7
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_M7_2
	db	CPU_BRAND_CYRIX	,SMI_NONE	 ,LEVEL_386	;TYPE_CX486SLC2
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_P24C
	db	CPU_BRAND_TI	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_TI486SXL
	db	CPU_BRAND_TI	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_TI486SXL2
	db	CPU_BRAND_UMC	,SMI_TYPE_OLD_AMD,LEVEL_486	;TYPE_U5
	db	CPU_BRAND_AMD	,SMI_NONE	 ,LEVEL_486	;TYPE_AMD486
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_586	;TYPE_P54C
	db	CPU_BRAND_TI	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_TI486SXLC
	db	CPU_BRAND_TI	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_TI486SXLC2
	db	CPU_BRAND_AMD	,SMI_NONE	 ,LEVEL_486	;TYPE_AMD486DX2
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_P24D
	db	CPU_BRAND_AMD	,SMI_NONE	 ,LEVEL_486	;TYPE_AMD486DX4
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_586	;TYPE_M1
	db	CPU_BRAND_AMD	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_AMD486PLUS
	db	CPU_BRAND_AMD	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_AMD486DX4PLUS
	db	CPU_BRAND_UMC	,SMI_TYPE_OLD_AMD,LEVEL_486	;TYPE_U486SX2
	db	CPU_BRAND_UMC	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_U486DX
	db	CPU_BRAND_UMC	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_U486DX2
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_M9
	db	CPU_BRAND_CYRIX	,SMI_TYPE_CYRIX	 ,LEVEL_486	;TYPE_CYRIX_DX4
	db	CPU_BRAND_INTEL	,SMI_TYPE_INTEL	 ,LEVEL_686	;TYPE_P6
	db	CPU_BRAND_AMD	,SMI_TYPE_INTEL	 ,LEVEL_486	;TYPE_X5
	db	CPU_BRAND_AMD	,SMI_TYPE_INTEL	 ,LEVEL_586	;TYPE_AMD5K86
	db	CPU_BRAND_CYRIX ,SMI_TYPE_CYRIX	 ,LEVEL_586	;TYPE_CYRIX_GXM

;;;;; ;Table for CPU clock over 255Mhz
;;;;; CPU_Over255MHz:
;;;;; 		db	400-256, 400-256-2,	CPU66		;66x6
;;;;; 		db	373-256, 373-256-2,	CPU83		;83x4.5
;;;;; 		db	366-256, 366-256-2,	CPU66		;66x5.5
;;;;; 		db	350-256, 350-256-2,	CPU100		;100x3.5
;;;;; 		db	333-256, 333-256-2,	CPU66		;66x5
;;;;; 		db	300-256, 300-256-2,	CPU66		;66x4.5
;;;;;
;;;;; 		DB	290-256, 290-256-2,	CPU83		;83X3.5
;;;;; 		db	266-256, 266-256-2,	CPU66		;66x4
;;;;; 		db	0					;end of table
;;;;;
;;;;; ;Clock table for P5-class CPUs
;;;;; NewCPU_Int_Clock_Tbl:
;;;;;
;;;;; ifdef	CLOCK_TBL_FOR_ICWORK
;;;;; 		db	250,	246,	CPU66		;83*3
;;;;; ifndef	NO_CPU_240MHZ_SUPPORT
;;;;; 		db	240,	236,	CPU60		;60x4
;;;;; endif;	NO_CPU_240MHZ_SUPPORT
;;;;; 		db	233,	228,	CPU66		;66x3.5
;;;;; 		db	225,	223,	CPU75		;75x3
;;;;;
;;;;; 		db	210,	205,	CPU60		;60x3.5
;;;;; 		db	200,	194,	CPU66		;66x3
;;;;;
;;;;; 		db	188,	185,	CPU66		;75*2.5
;;;;; 		db	180,	176,	CPU60		;60x3
;;;;; 		db	166,	163,	CPU66		;66x2.5
;;;;; 		db	150,	147,	CPU60		;60x2.5
;;;;;
;;;;; 		db	133,	128,	CPU66		;66x2	;here special
;;;;; 		db	125,	124,	CPU50		;50x2.5
;;;;; 		db	120,	118,	CPU60		;60x2	;here special
;;;;; 		db	117,	115,	CPU66		;66x1.75
;;;;; 		db	110,	109,	CPU50		;55x2
;;;;; 		db	105,	103,	CPU60		;60x1.75
;;;;; 		db	100,   	 98,	CPU66		;66x1.5	;here special
;;;;;
;;;;; else;	CLOCK_TBL_FOR_ICWORK
;;;;;
;;;;; ifdef	CLOCK_TBL_FOR_ICS
;;;;; 		db	250,	248,	CPU66		;83*3
;;;;; ifndef	NO_CPU_240MHZ_SUPPORT
;;;;; 		db	240,	238,	CPU60		;60x4
;;;;; endif;	NO_CPU_240MHZ_SUPPORT
;;;;;
;;;;; ifdef	Lower_233Mhz_FOR_ICS
;;;;; 		db	233,	223,	CPU66		;66x3.5
;;;;; else;	Lower_233Mhz_FOR_ICS
;;;;; 		db	233,	230,	CPU66		;66x3.5
;;;;; endif;	Lower_233Mhz_FOR_ICS
;;;;;
;;;;; ifndef	NO_CPU_225MHZ_SUPPORT_FOR_ICS
;;;;; 		db	225,	223,	CPU75		;75x3
;;;;;
;;;;; endif;	NO_CPU_225MHZ_SUPPORT_FOR_ICS
;;;;;
;;;;; ifndef	NO_CPU_210MHZ_SUPPORT_FOR_ICS
;;;;; 		db	210,	208,	CPU60		;60x3.5
;;;;; endif;	NO_CPU_210MHZ_SUPPORT_FOR_ICS
;;;;;
;;;;; 		db	200,	186,	CPU66		;66x3
;;;;; 		db	193,	181,	CPU50		;55*3.5
;;;;;
;;;;; ifndef	NO_CPU_188MHZ_SUPPORT_FOR_ICS
;;;;; 		db	188,	174,	CPU66		;75*2.5
;;;;; endif;	NO_CPU_188MHZ_SUPPORT_FOR_ICS
;;;;; 		db	180,	170,	CPU60		;60x3
;;;;; ifndef	NO_CPU_175MHZ_SUPPORT_FOR_ICS
;;;;; 		db	175,	164,	CPU50		;50x3.5
;;;;; endif;	NO_CPU_175MHZ_SUPPORT_FOR_ICS
;;;;; 		db	166,	154,	CPU66		;66x2.5
;;;;; 		db	150,	138,	CPU60		;60x2.5
;;;;; 		db	133,	123,	CPU66		;66x2
;;;;; ifndef	NO_CPU_125MHZ_SUPPORT_FOR_ICS
;;;;; 		db	125,	115,	CPU50		;50x2.5
;;;;; endif;	NO_CPU_125MHZ_SUPPORT_FOR_ICS
;;;;; 		db	120,	110,	CPU60		;60x2
;;;;; 		db	117,	106,	CPU66		;66x1.75
;;;;; 		db	110,	101,	CPU50		;55x2
;;;;; ifndef	NO_CPU_105MHZ_SUPPORT_FOR_ICS
;;;;; 		db	105,	 96,	CPU60		;60x1.75
;;;;; endif;	NO_CPU_105MHZ_SUPPORT_FOR_ICS
;;;;; ifndef	Higher_100Mhz_FOR_ICS
;;;;; 		db	100,   	 89,	CPU66		;66x1.5
;;;;; else;	Higher_100Mhz_FOR_ICS
;;;;; 		db	100,   	 93,	CPU66		;66x1.5
;;;;; endif;	Higher_100Mhz_FOR_ICS
;;;;; else;	CLOCK_TBL_FOR_ICS
;;;;;
;;;;; 		db	250,	248,	CPU66		;83*3
;;;;; ifndef	NO_CPU_240MHZ_SUPPORT
;;;;; ifdef	Higher_240MHz_Tbl
;;;;; 		db	240,	240,	CPU60		;60x4
;;;;; else;	Higher_240MHz_Tbl
;;;;; 		db	240,	238,	CPU60		;60x4
;;;;; endif;	Higher_240MHz_Tbl
;;;;; endif;	NO_CPU_240MHZ_SUPPORT
;;;;;
;;;;; 		db	233,	230,	CPU66		;66x3.5
;;;;; 		db	225,	223,	CPU75		;75x3
;;;;;
;;;;; 		db	210,	208,	CPU60		;60x3.5
;;;;; 		db	200,	195,	CPU66		;66x3
;;;;; ifndef	No_55MHz
;;;;; 		db	193,	190,	CPU50		;55*3.5
;;;;; endif	;No_55MHz
;;;;; 		db	190,	189,	CPU95
;;;;;
;;;;; 		db	188,	185,	CPU66		;75*2.5
;;;;; 		db	180,	179,	CPU60		;60x3
;;;;; 		db	175,	174,	CPU50		;50x3.5
;;;;; 		db	166,	165,	CPU66		;66x2.5
;;;;; 		db	150,	149,	CPU60		;60x2.5
;;;;;
;;;;; 		db	133,	132,	CPU66		;66x2
;;;;; 		db	125,	124,	CPU50		;50x2.5
;;;;; 		db	120,	119,	CPU60		;60x2
;;;;; 		db	117,	115,	CPU66		;66x1.75
;;;;; ifndef	No_55MHz
;;;;; 		db	110,	109,	CPU50		;55x2
;;;;; endif	;No_55MHz
;;;;; ifndef	No_105MHz
;;;;; 		db	105,	103,	CPU60		;60x1.75
;;;;; endif;	No_105MHz
;;;;; 		db	100,   	 99,	CPU66		;66x1.5
;;;;;
;;;;; endif;	CLOCK_TBL_FOR_ICS
;;;;; endif;	CLOCK_TBL_FOR_ICWORK
;;;;;
;;;;; 		db	 90,   	 88,	CPU60		;60x1.5
;;;;; 		db	 90,	 86,	CPU50		;50x1.75
;;;;; ifndef	No_55MHz
;;;;; 		db	 83,   	 82,	CPU50		;55x1.5
;;;;; endif	;No_55MHz
;;;;;
;;;;; 		db	 75,   	 70,	CPU50		;50x1.5
;;;;; 		db	 66,   	 65,	CPU66		;66x1
;;;;; 		db	 60,   	 59,	CPU66		;60x1
;;;;; 		db	 50,   	 49,	CPU66		;50x1
;;;;; 		db	 0		;end of table

;Clock detection for 386,486 & 586 CPUs

		ALIGN	16
		Public	MOV_SHAD_OFF
MOV_SHAD_OFF	EQU	00000H
		Public	MOV_SHAD_SEG

MOV_SHAD_SEG	EQU	5000h

		Public	Measure_CPU_Speed
Measure_CPU_Speed	proc	near

;--------------------------------------
;Copy code into RAM for speed detection
;--------------------------------------

		push	0f000h
		pop	ds

;--------------------------------------------------
;Set KB high speed for test & save results(push bx)
;--------------------------------------------------

ifdef	TOGGLE_8042_FOR_CPU_CLK_DETECT
		mov	al,1		;Set low speed for test
		call	F000_Out_8042_Pin
endif;	TOGGLE_8042_FOR_CPU_CLK_DETECT

		in	al,PORT61
		IODELAY
		push	ax 			;save PORT61 value

	;execute the CPU detection code in DRAM

		call	far ptr S_CPU

	;return register values after calling S_CPU are
	; BH - CPU host clock
	; DL - CPU clock mode (x1, x2 ,x3 or x4)
		mov	al,bh
		mul	dl
		mov	si,ax

		pop	ax			;restore PORT61 value
		out	PORT61,al
		IODELAY

ifdef	TOGGLE_8042_FOR_CPU_CLK_DETECT
	;Save KB high speed result

		push	dx
		push	bx

;-------------------------
;Set KB low speed for test
;-------------------------

		xor	al,al			;Set high speed for test
		call	F000_Out_8042_Pin

		in	al,PORT61		;save PORT61 value
		IODELAY
		push	ax

		call	far ptr S_CPU

		pop	ax			;restore PORT61 value
		out	PORT61,al
		IODELAY

;--------------------------------------------------------------
;compare results of KB high & KB low speed, take the higher one
;--------------------------------------------------------------

	;restore KB high speed results in ax, di

		mov	al,bh
		mul	dl
		cmp	ax,si
		pop	ax
		pop	di

		jae	AUTO_CPUS_READY

	;use KB high speed result

		mov	bx,ax
		mov	dx,di

AUTO_CPUS_READY:
endif;	TOGGLE_8042_FOR_CPU_CLK_DETECT

	;write CPU_INTERNAL_CLOCK[bp] with tested value

		mov	al,bh			;system clock(integer) in AL
		mul	dl			;Sing/doub/treb value in DL

		mov	CPU_INT_CLOCK[bp],ax	;actual internal CPU clock

		mov	dl,FIXED_DISK_STEP[bp]	;get CPU type
		and	dl,CPU_TYPE_MASK	;get CPU type

	;special table for P24T , because the clock mode is x2.5

		cmp	dl,TYPE_P24T
		jne	Not_P24T_2Point5
		test	byte ptr OVERRIDE[bp],DOUBLE_CLOCK
		jz	Not_P24T_2Point5
		mov	si,offset P24T_Int_Clock_Tbl
;;;;; 		jmp	R_Off_Clk
Not_P24T_2Point5:

;;;;; 		jmp	Not_Pentium
;;;;; R_Off_Clk:

;;;;; 	;far call Round_Off_Clock
;;;;;
;;;;; 		FAR_CALL <offset Round_Off_Clock>,0E000h
;;;;;
;;;;; 		mov	CPU_INT_CLOCK[bp],bl	;actual internal CPU clock
;;;;;
;;;;; 		push	G_RAM
;;;;; 		pop	es
;;;;;
;;;;; 		mov	bl,cs:[si+2]			;SI+2 = system clock
;;;;; 							;change Ratio
;;;;; 		mov	byte ptr es:[CPU_CLOCK],bl
;;;;;
;;;;; 	Not_P54C:
;;;;; 	Not_Pentium:

;Show 100Mhz if 99Mhz
		cmp	byte ptr CPU_INT_CLOCK[bp],132
		je	Set_133
		cmp	byte ptr CPU_INT_CLOCK[bp],99
		jne	@F
Set_133:
		inc	byte ptr CPU_INT_CLOCK[bp]
	@@:
ifdef	TOGGLE_8042_FOR_CPU_CLK_DETECT
		mov	al,1
		call	F000_Out_8042_Pin
endif;	TOGGLE_8042_FOR_CPU_CLK_DETECT

;-------------------
;Clear temporary RAM
;-------------------

		mov	ax,G_RAM
		mov	es,ax
		assume	es:G_RAM

;----------------------------
;Special treatment for TI CPU
;----------------------------

IF	BIOS_SUPPORT_TI_CPU
		cmp	bl,CPU33
		ja	@F
		mov	al,FIXED_DISK_STEP[bp]
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_TI486SXL
		mov	dx,CPU_TI486SXL2
		je	Set_TI_CPU
		cmp	al,TYPE_TI486SXLC
		jne	@F
		mov	dx,CPU_TI486SXLC2
Set_TI_CPU:
		test	byte ptr FIXED_DISK_STEP[bp],01H;coprocess or exist
		jz	No_Copro
		or	dl,01H				;restore copro. flag
No_Copro:
		mov	byte ptr FIXED_DISK_STEP[bp],dl
		mov	ah,FIXED_DISK_STEP[bp]
		mov	es:CPU_TYPE_FLAG,ah
		mov	al,CMOS_AWARD_2 NMI_OFF
		call	F000_Set_Cmos

		mov	ah,byte ptr OVERRIDE[bp]
		and	ah,Not Clock_Mode
		or	ah,dh
		mov	byte ptr OVERRIDE[bp],ah
		mov	al,OVERRIDE NMI_OFF
		call	F000_Set_Cmos

		mov	al,0c0h
		out	22h,al
		NEWIODELAY
		in	al,23h
		NEWIODELAY

		or	al,40h
		mov	ah,al

		mov	al,0c0h
		out	22h,al
		NEWIODELAY
		mov	al,ah
		out	23h,al
		NEWIODELAY

		shl	byte ptr CPU_INT_CLOCK[bp],1	;double clock

@@:
ENDIF	;BIOS_SUPPORT_TI_CPU

		mov	byte ptr es:CPU_CLOCK,bl
CpuSpeedEnd:
		clc
		ret

Measure_CPU_Speed	endp

DIVID		MACRO
		mov	ax,di
		div	bx
		endm
PORT61		EQU	61H
PORT8254	EQU	42H
DATA8254	EQU	43H
COUNT		EQU	3EH

;-----------------------------------------------------------------
;Input	:	None
;Output :	BH : System Clock in interger
;		BL : System Clock i.e. 10h = 16MHz
;				       20h = 20MHz
;				       30h = 25MHz
;				       40h = 33MHz
;				       50h = 40MHz
;				       60h = 50MHz
;				       60h = 60MHz
;				       60h = 66MHz
;		DH : Actual CPU clock index found
;		DL : Single/Double/Trible
;-----------------------------------------------------------------
		ALIGN	16
S_Cpu		proc	far

		call	far ptr XMeasureNoRDTSCCpuClck

		mov	ax,26f5h	;dividend low word
		mov	dx,005ah	;dividend high word

		mov	bh,byte ptr FIXED_DISK_STEP[bp]
		and	bh,CPU_TYPE_MASK

IF	BIOS_SUPPORT_486
		cmp	bh,TYPE_M9
		jne	Not_M9
		mov	ax,4632h
		mov	dl,6Dh
		jmp	Not_Cyrix_Cpu
Not_M9:

		cmp	bh,TYPE_U5
		jne	Not_U5
		mov	ax,0dbb8h
		mov	dl,52h
		jmp	Not_Cyrix_Cpu
Not_U5:
ENDIF	;BIOS_SUPPORT_486

IF	BIOS_SUPPORT_IBM_CPU
		cmp	byte ptr CPU_BRAND[bp],CPU_BRAND_IBM
		je	Yes_Cyrix_Cpu
ENDIF	;BIOS_SUPPORT_IBM_CPU

		cmp	byte ptr CPU_BRAND[bp],CPU_BRAND_CYRIX
		je	Yes_Cyrix_Cpu

IF	BIOS_SUPPORT_TI_CPU
		cmp	byte ptr CPU_BRAND[bp],CPU_BRAND_TI
		je	Yes_Cyrix_Cpu
ENDIF	;BIOS_SUPPORT_TI_CPU

		jmp	Not_Cyrix_Cpu
Yes_Cyrix_Cpu:
		mov	ax,64a8h
		mov	dl,4eh
Not_Cyrix_Cpu:

		div	cx
		xor	bl,bl
Sub_1:
		inc	bl
		sub	ax,100
		jc	Fin_0
		jz	No_Carry
		jmp	Sub_1
Fin_0:
		add	ax,100

		cmp	al,50
		jae	No_Carry
		dec	bl
No_Carry:
;------------------------------------------------------------------
;calculate system clock by checking CPU type (Single/Double/Treble)
;------------------------------------------------------------------

IF	BIOS_SUPPORT_486
		mov	al,byte ptr FIXED_DISK_STEP[bp]
		and	al,CPU_TYPE_MASK
		cmp	al,TYPE_P24C
		jne	Not_P24C
		cmp	bl,70			;clock below 70Mhz
		jae	Not_P24C
		;set double clock
		and	byte ptr OVERRIDE[bp],NOT CLOCK_MODE
		or	byte ptr OVERRIDE[bp],DOUBLE_CLOCK
		jmp	Xchg_CPU_Mode_OK
Not_P24C:

		cmp	bl,50
		jae	Not_P24T_X1
		cmp	al,TYPE_P24T
		jne	Not_P24T_X1
		and	byte ptr OVERRIDE[bp],NOT CLOCK_MODE
Not_P24T_X1:

		mov	al,byte ptr FIXED_DISK_STEP[bp]
		and	al,CPU_TYPE_MASK

		cmp	al,TYPE_AMD486DX2
		je	Xchg_AMD_CPU
		cmp	al,TYPE_486DX2
		jne	Not_AMDDX4
Xchg_AMD_CPU:

		cmp	bl,90
		jb	Not_AMDDX4
		;set three clock mode
		and	byte ptr OVERRIDE[bp],NOT CLOCK_MODE
		or	byte ptr OVERRIDE[bp],THREE_CLOCK
		mov	al,byte ptr FIXED_DISK_STEP[bp]
		and	al,NOT_CPU_TYPE_MASK
		or	al,TYPE_AMD486DX4
		mov	byte ptr FIXED_DISK_STEP[bp],al
		jmp	Xchg_CPU_Mode_OK
Not_AMDDX4:
ENDIF	;BIOS_SUPPORT_486

Xchg_CPU_Mode_OK:

		xor	bh,bh
		mov	ax,bx

		mov	bl,1

		test	byte ptr OVERRIDE[bp],FOUR_CLOCK
		jz	Three_Freq
		mov	bl,4
		jmp	Single_Freq
Three_Freq:
		test	byte ptr OVERRIDE[bp],THREE_CLOCK
		jz	Double_Freq

		mov	bl,3
		jmp	Single_Freq
Double_Freq:
		test	byte ptr OVERRIDE[bp],DOUBLE_CLOCK
		jz	Single_Freq

		mov	bl,2
Single_Freq:
		div	bl
		add	al,3	       ;tolerance
Skip_Gap:

		mov	dh,al	;DH = Actual CPU clock found
		mov	dl,bl	;DL = Single/Double/Trible

		mov	si,offset Sys_Clock_Tbl
		mov	cx,Sys_Clock_Tbl_Len

	;far call Round_Off_Clock

		FAR_CALL <offset Round_Off_Clock>,0E000h

		ret

;;;;; Check_586_Cpu	proc	near
;;;;;
;;;;; 		cmp	sp, 0FFFFh	;always return not 586
;;;;; 		ret
;;;;;
;;;;; Check_586_Cpu	endp

		even

Last_S_Cpu	Label	Near
S_Cpu		endp

;[]--------------------------------------------------------------[]
;Input	:	AL = Clock to be compared
;		SI = table offset
;		     (format: reference System_Clock_Table)
;		CX = no of entries
;
;Output :	BH = reference value (see System_Clock_Table)
;		BL = round-offed value
;		SI = offset which round-offed value locates
;[]--------------------------------------------------------------[]
Round_Off_Clock Proc	Far
Next_Clk_Tbl:
		mov	bx,cs:[si]
		cmp	al,bh
		jae	@F
		cmp	byte ptr cs:[si+3],0	;last table ?
		je	@F
		add	si,3			;next table
		jmp	Next_Clk_Tbl
@@:
		retf
Round_Off_Clock Endp

;--------------------------------------------------------------------
;			round	  value 	value
;			offed	  for		to be put
;			output	  reference	into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
Sys_Clock_Tbl:
		db	CPU66,		66,	CPU66
		db	CPU60,		60,	CPU60
		db	CPU50,		50,	CPU50
		db	CPU40,		40,	CPU40
		db	CPU33,		33,	CPU33
		db	CPU25,		25,	CPU25
		db	CPU20,		20,	CPU20
		db	CPU16,		16,	CPU16
		db	0		;end of table
Sys_Clock_Tbl_Len	EQU	($ - offset Sys_Clock_Tbl)/3

;--------------------------------------------------------------------
;			round	  value 	value
;			offed	  for		to be put
;			output	  reference	into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
CPU_Int_Clock_Tbl:

;--------------------------------------------------------------------
;			round	  value 	value
;			offed	  for		to be put
;			output	  reference	into G_RAM:CPU_CLOCK
;--------------------------------------------------------------------
M1_Int_Clock_Tbl:

P24T_Int_Clock_Tbl:
		db	125,	       110,	CPU50
		db	100,		95,	CPU40
		db	 83,		75,	CPU33
		db	 63,		55,	CPU25
		db	 50,		45,	CPU20
		db	0

Cpu_Speed_Msg:	db	'CPU Clock',0

;Function : Program MTRR for CPUs like P6 or P55CT
;Input	  : AL = 0 - program MTRR for conventional memory (0-640K)
;	       = 1 - program MTRR for extended memory (1Mb to top of memory)
;	    Bit 7 = 1 - 15-16MB memory hole is disabled(P6 only)
;	    esi - extended memory size
;	    BL = 0 - L2 cache status (0-disabled, 1-enabled)

;	    BH = L2 Cacheable range 000=512Mb , 001=1Gb, 010=2Gb, 011=4Gb
;				    100=8Gb   , 101=16Gb,110=32Gb,111=64Gb
;		 only for Pentium II CPUs

;Output   : none
ifdef	Special_Align_for_M1_Clock_unstable

		ALIGN	16
endif;	Special_Align_for_M1_Clock_unstable
		Public	Set_Cpu_MtRR
Set_Cpu_MtRR	proc	near

		ret
Set_Cpu_MtRR	endp

		Public	Enable_M1_FarHit
Enable_M1_FarHit	proc	near

;;;;; ifndef	P6_BIOS_ONLY
;;;;;
;;;;; 		call	Check_M1_Cpu
;;;;; 		jne	Not_M1_Cpu
;;;;;
;;;;; 		F000_call	UNlock_Cyrix
;;;;;
;;;;; ifdef	HIGH_6X86_L2_HIT_RATE
;;;;; ;Enable WT_ALLOC of CCR5 to improve L2 cache hit rate for CCT386.EXE
;;;;; ;For 256Kb cache it improve hit rate from 26% upto 62% for 6x86 CPUs
;;;;;
;;;;; ifdef	Disable_WT_ALLOC_When_Cyrix_PR266
;;;;;  		mov	cl,0FEh			; DIR0 of M2 CPU
;;;;; 		call	F000_Get_Cyrix
;;;;;  						; AL = 51 : 'x 2'
;;;;;  						; AL = 52 : 'x 2.5'
;;;;;  						; AL = 53 : 'x 3'
;;;;; 		cmp	al,52h
;;;;; 		jnz	Not_Cyrix_PR266
;;;;;  		cmp	byte ptr CPU_INT_CLOCK[bp],208	;208Mhze(PR266) ?
;;;;; 		jnz	Not_Cyrix_PR266
;;;;; 		jmp	Skip_WT_ALLOC
;;;;; Not_Cyrix_PR266:
;;;;; endif;	Disable_WT_ALLOC_When_Cyrix_PR266
;;;;;
;;;;; ifdef	Disable_WT_ALLOC_When_Cyrix_83_x3
;;;;;  		mov	cl,0FEh			; DIR0 of M2 CPU
;;;;; 		call	F000_Get_Cyrix
;;;;;  						; AL = 51 : 'x 2'
;;;;;  						; AL = 52 : 'x 2.5'
;;;;;  						; AL = 53 : 'x 3'
;;;;; 		cmp	al,53h
;;;;; 		jnz	Not_MII_333
;;;;;  		cmp	byte ptr CPU_INT_CLOCK[bp],250	;250Mhze(MII333) ?
;;;;; 		jnz	Not_MII_333
;;;;; 		jmp	Skip_WT_ALLOC
;;;;; Not_MII_333:
;;;;; endif;	Disable_WT_ALLOC_When_Cyrix_83_x3
;;;;;
;;;;; 		mov	cl,0E9H			;CCR5
;;;;; 		call	F000_Get_Cyrix
;;;;; 		or	al,01H			;enable WT_ALLOC
;;;;; 		call	F000_Set_Cyrix
;;;;; Skip_WT_ALLOC:
;;;;; endif;	HIGH_6X86_L2_HIT_RATE
;;;;;
;;;;; 	;set bit 6 of index 30H
;;;;; 		mov	cl,30H
;;;;; 		call	F000_Get_Cyrix
;;;;; 		or	al,40H
;;;;; 		call	F000_Set_Cyrix
;;;;;
;;;;; 	;enable far hit
;;;;; 		mov	ebx,28h
;;;;; 		db	0fh,26h,0cbh		;mov tr1,ebx
;;;;; 		db	0fh,24h,0d0h		;mov eax,tr2
;;;;; 		and	al,NOT 02H		;enable far hits
;;;;; 		db	0fh,26h,0d0h		;mov tr2,eax
;;;;;
;;;;; 	;clear bit 6 of index 30H
;;;;; 		mov	cl,30H
;;;;; 		call	F000_Get_Cyrix
;;;;; 		and	al,NOT 40H
;;;;; 		call	F000_Set_Cyrix
;;;;;
;;;;; 		F000_call lock_Cyrix
;;;;;
;;;;; Not_M1_Cpu:
;;;;; endif;	P6_BIOS_ONLY

		ret
Enable_M1_FarHit	endp

		public	F000_Set_Cyrix
F000_Set_Cyrix	Proc	Near
		F000_Call Set_Cyrix
		ret
F000_Set_Cyrix	Endp

F000_Get_Cyrix	Proc	Near
		F000_Call Get_Cyrix
		ret
F000_Get_Cyrix	Endp

;[]========================================================================[]
;Name	  :	Prg_K5_Write_Allocate
;
;Function :	To enable the AMD K5 CPU's write allocation function
;
;Input	  :	dword ptr EXT_MEM_SIZE[bp] in terms of 1K
;
;Output	  :	None
;[]========================================================================[]
		Public	Prg_K5_Write_Allocate
Prg_K5_Write_Allocate	Proc	Near

		ret

Prg_K5_Write_Allocate	Endp

ECODE		ENDS

XGROUP		GROUP	XCODE
XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP,ES:XGROUP

DIVID		MACRO
		mov	ax,di
		div	bx
		endm
PORT61		EQU	61H
PORT8254	EQU	42H
DATA8254	EQU	43H
COUNT		EQU	3EH

		align	16
;Function : Measure CPU clock without RDTSC instruction
;Input    : none
;Output   : CX - duration time of one CPU clock
;Note     : This routine will be executed in base memory.
;
XMeasureNoRDTSCCpuClck	proc	far

		cli
		mov	al,0fch 	;disable counter 2
		out	PORT61,al
		SIODELAY
		mov	al,0b4h 	;program counter 2
		out	DATA8254,al
		IODELAY
		xor	al,al
		out	PORT8254,al
		IODELAY
		out	PORT8254,al
		IODELAY

		mov	di,7aaah	;dividend
		mov	bx,5555h	;divisor
		xor	dx,dx
		mov	cx,COUNT	;count
		mov	al,0fdh 	;enable counter
		out	PORT61,al
		SIODELAY
		ALIGN	16
Divid_33:
		DIVID			;divide 1
		DIVID			;divide 2
		DIVID			;divide 3
		DIVID			;divide 4
		DIVID			;divide 5
		DIVID			;divide 6
		DIVID			;divide 7
		DIVID			;divide 8
		DIVID			;divide 9
		DIVID			;divide 10
		DIVID			;divide 11
		DIVID			;divide 12
		DIVID			;divide 13
		DIVID			;divide 14
		DIVID			;divide 15
		DIVID			;divide 16
		DIVID			;divide 17
		DIVID			;divide 18
		DIVID			;divide 19
		DIVID			;divide 20
		DIVID			;divide 21
		DIVID			;divide 22
		DIVID			;divide 23
		DIVID			;divide 24
		DIVID			;divide 25
		DIVID			;divide 26
		DIVID			;divide 27
		DIVID			;divide 28
		DIVID			;divide 29
		DIVID			;divide 30
		DIVID			;divide 31
		DIVID			;divide 32
		DIVID			;divide 33
		dec	cx
		jz	Finish
		jmp	Divid_33
Finish:
		mov	al,0fch 	;stop counter 2
		out	61h,al
		SIODELAY
		in	al,PORT8254	;read counter 2 low byte
		IODELAY
		mov	ah,al
		in	al,PORT8254	;read counter 2 high byte
		IODELAY
		xchg	ah,al
		mov	si,ax		;store result

		xor	dx,dx
		mov	cx,COUNT	;count
		mov	al,0fdh 	;enable counter
		out	PORT61,al
		SIODELAY
		ALIGN	16
Divid_1:
		DIVID			;divide 1
		dec	cx
		jz	short Finish1
		jmp	short Divid_1
Finish1:
		mov	al,0fch 	;stop counter 2
		out	61h,al
		SIODELAY
		in	al,PORT8254	;read counter 2 low byte
		IODELAY
		mov	ah,al
		in	al,PORT8254	;read counter 2 high byte
		IODELAY
		xchg	ah,al
		mov	cx,ax
		sub	cx,si		;result 2 - result 1

		ret
XMeasureNoRDTSCCpuClck	endp
XCODE		ENDS

ENDIF	;COMPILE_FOR_E0

IFE     COMPILE_FOR_E0

		extrn	F000_call_proc:near
		extrn	Ct_MemHole_Status:Near
		extrn	F000_Shadow_W:Near
		extrn	F000_Shadow_R:Near

		extrn	F000_GetItem_Value:near

		extrn	F000_Display_Char:Near
		extrn	F000_Display_String:Near

		extrn	DISPLAY_CS_STRING:Near
		extrn	SYSCFG_CPU_CLOCK1:Near

		extrn	fProc_Disp_Word_Int3:far
		extrn	fProc_Disp_Byte_Int2:far
		extrn	X_Display_Char:near
		extrn	X_Display_CS_String:near
.LIST
EGROUP		GROUP	ECODE
ECODE		SEGMENT USE16 PARA PUBLIC 'ECODE'
		ASSUME	CS:EGROUP,DS:G_RAM,ES:EGROUP

;Function : return cache size in AL for display
;Input    : DL - CPU register value to indicate cache size
;		 40H - No L2 cache
;		 41H - 128K
;		 42H - 256K
;		 43H - 512K
;		 44H - 1Mb
;		 45H - 2Mb
;Output   : AL - cache size for BIOS to display
;           AL -  0 = 0K, 1=16K , 2=32K , 3=64K , 4=128K , 5=256K
;	          6 =512K, 7=1024K ,etc...
		Public	Convert_P6L2_Cache
Convert_P6L2_Cache	proc	near
		ret
Convert_P6L2_Cache	endp

;=============================================================================
;FUNC:	CPU_DISPLAY
;
;DESC:	Returns the length and description string for the CPU.
;
;IN:	NONE
;OUT:	CS:SI	String pointer
;
;SAVES:	DX
;=============================================================================
		PUBLIC	CPU_DISPLAY
CPU_DISPLAY	PROC	Near

		mov	al,FIXED_DISK_STEP[bp]
		and	al,CPU_TYPE_MASK

IF	BIOS_SUPPORT_TI_CPU
		mov	si,offset TI_486dx4_str		;assume TI CPU !
		cmp	al,TYPE_CYRIX_DX4		;cyrix DX 4 ?
		jne	Not_CyDx4
	;read DIR 0 value , it is Ti486DX4 if value is 81H
		push	ax
		mov	al,0FEh
		out	22h,al
		in	al,23h
		cmp	al,81h				;TI 486DX4 CPU ?
		pop	ax
		je	Cpu_Str_Ok		;yes
Not_CyDx4:
ENDIF	;BIOS_SUPPORT_TI_CPU

		cmp	al,NUM_OF_CPU_TYPE
		mov	si,offset Unknown_Str
		ja	@F
		movzx	si,al
		mov	si,word ptr cs:CPU_TYPE_STRS[si]
	@@:

;;;;; ifndef	K7_CPU_SUPPORT
;;;;;
;;;;;		cmp	si,offset Cpu_P6_Str	;is P6 CPU ?
;;;;;		jne	Not_P6Cpu
;;;;;Not_P6Cpu:
;;;;;
;;;;; endif;	K7_CPU_SUPPORT

IF	BIOS_SUPPORT_486
		cmp	al,TYPE_486DX2
		jne	@F
		test	byte ptr FIXED_DISK_STEP[bp],COPROCESSOR
		jz	@F
		mov	si,offset cpu_486dx2_str
	@@:
		cmp	al,TYPE_M7_2
		jne	@F

		mov	al,0FFh
		out	22h,al
		in	al,23h
		test	al,80h			;TI CPU ?
		jz	@F		;No
		mov	si,offset TI_486dx2_str
	@@:
ENDIF	;BIOS_SUPPORT_486
Cpu_Str_Ok:

IF	BIOS_SUPPORT_486
;display "P90" for 160Mhz and "P75" for 133Mhz AMD X5 CPUs
	    	cmp	si,offset Cpu_AmdDX5_Str	;AMD X5 ?
		jne	Not_Amd_X5Cpu

		cmp	byte ptr CPU_INT_CLOCK[bp],160	;160Mhz ?
		jne	Not_Amd_X5Cpu

		mov	si,offset Cpu_AmdDX5_160_Str	;show P90 for 160Mhz

Not_Amd_X5Cpu:

	    	cmp	si,offset Cpu_AMD486DX4Plus_Str	;Enhanced Am486DX4 ?
		jne	Not_Amd_150_Cpu

		cmp	byte ptr CPU_INT_CLOCK[bp],150	;150Mhz ?
		jne	Not_Amd_150_Cpu

		mov	si,offset Cpu_AmdDX5_150_Str	;show P75+ for 150Mhz
Not_Amd_150_Cpu:

endif;	BIOS_SUPPORT_486

		ret

CPU_DISPLAY	ENDP

CPU_TYPE_STRS:
		dw	offset cpu_386dx_str
		dw	offset cpu_386sx_str
		dw	offset cpu_386sl_str
		dw	offset cpu_486dx_str
		dw	offset cpu_486sx_str
		dw	offset cpu_486sx2_str
		dw	offset cpu_Cx486slc_str
		dw	offset cpu_Cx486dlc_str
		dw	offset cpu_ibm386slc_str
		dw	offset cpu_ibm486slc2_str
		dw	offset Cpu_P24t_str
		dw	offset Cpu_486s_Str
		dw	offset Cpu_486s2_Str
		dw	offset Cpu_586_Str
		dw	offset Cpu_486dxS_Str
		dw	offset Cpu_486sxS_Str
		dw	offset Cpu_486dx2S_Str
		dw	offset cpu_ibm486dlc3_str
		dw	offset Cpu_M7_Str
		dw	offset Cpu_M7_2_Str
		dw	offset Cpu_Cx486slc2_Str
		dw	offset Cpu_P24c_Str
		dw	offset Cpu_TI486SXL_Str
		dw	offset Cpu_TI486SXL2_Str
		dw	offset Cpu_U5_Str
		dw	offset Cpu_AMD486_Str
		dw	offset Cpu_P54c_Str
		dw	offset Cpu_TI486SXLC_Str
		dw	offset Cpu_TI486SXLC2_Str
		dw	offset Cpu_AMD486DX2_Str
		dw	offset Cpu_P24D_Str
		dw	offset Cpu_AMD486DX4_Str
		dw	offset Cpu_M1_Str
		dw	offset Cpu_AMD486Plus_Str
		dw	offset Cpu_AMD486DX4Plus_Str
		dw	offset Cpu_U486sx2_Str
		dw	offset Cpu_U486DX_Str
		dw	offset Cpu_U486DX2_Str
		dw	offset Cpu_M9_Str
		dw	offset Cpu_Cyrix_Dx4_Str
		dw	offset Cpu_P6_Str
		dw	offset Cpu_AmdDX5_Str
		dw	offset Cpu_AmdD5K86_Str
		dw	offset Cpu_CyrixGXm_Str
NUM_OF_CPU_TYPE	EQU	($ - offset CPU_TYPE_STRS)

;-------------------------- 386 CPU Strings --------------------------

IF	BIOS_SUPPORT_386

	cpu_386dx_str:		db	"80386DX",0
 ifdef	M6117_CPU
	cpu_386sx_str:		db	"ALi-M6117",0
 else	;M6117_CPU
	cpu_386sx_str:		db	"80386SX",0
 endif	;M6117_CPU
	cpu_386sl_str:		db	"RapidCAD",0
	Cpu_Cx486slc2_Str:	db	"Cx486SLC2",0
	cpu_Cx486slc_str:	db	"Cx486SLC",0
	cpu_Cx486dlc_str:	db	"Cx486DLC",0

ELSE	;BIOS_SUPPORT_386

	cpu_386dx_str:
	cpu_386sx_str:
	cpu_386sl_str:
	Cpu_Cx486slc2_Str:
	cpu_Cx486slc_str:
	cpu_Cx486dlc_str:	db	0

ENDIF	;BIOS_SUPPORT_386

;-------------------------- 486 CPU Strings --------------------------

IF	BIOS_SUPPORT_486

	;----- Intel 486 -----

	cpu_486dx_str:		db	"80486DX",0
	cpu_486sx_str:		db	"80486SX",0
	cpu_487sx_str:		db	"80487SX",0
ifdef 	ELAN400
	cpu_486sx2_str:		db	"ElanSC400",0
else; 	ELAN400
	cpu_486sx2_str:		db	"80486SX2",0
endif; 	ELAN400
	cpu_486dx2_str:		db	"80486DX2",0
	Cpu_P24t_str:		db	"PENTIUM OverDrive",0

	Cpu_P24c_Str:		db	"DX4",0
	Cpu_P24D_Str:		db	"P24D",0

	;----- TI 486 -----

	TI_486dx2_str:		db	"TI486DX2",0
	TI_486dx4_str:		db	"TI486DX4",0

	;----- Cyrix 486 -----

	ifndef	No_Brand_For_CYRIXCPU

		Cpu_Cyrix_Dx4_Str:	db	"CxDX4",0
		Cpu_486s_Str:		db	"Cx486S",0
		Cpu_486s2_Str:		db	"Cx486S2",0
	ifdef	STPC_IDE
		Cpu_M7_Str:		db	"STPC",0
	else;	STPC_IDE
		Cpu_M7_Str:		db	"Cx486DX",0
	endif;	STPC_IDE
		Cpu_M7_2_Str:		db	"Cx486DX2",0

	else	;No_Brand_For_CYRIXCPU

		Cpu_Cyrix_Dx4_Str:	db	"DX4",0
		Cpu_486s_Str:		db	"486S",0
		Cpu_486s2_Str:		db	"486S2",0
		Cpu_M7_Str:		db	"486DX",0
		Cpu_M7_2_Str:		db	"486DX2",0

	endif	;No_Brand_For_CYRIXCPU

		Cpu_M9_Str:		db	"Cx5x86",0

	;----- UMC 486 -----

	ifndef	No_Brand_For_UMCCPU

		Cpu_U5_Str:		db	"U486SX",0
		Cpu_U486sx2_Str:	db	"U486SX2",0
		Cpu_U486DX_Str:		db	"U486DX",0
		Cpu_U486DX2_Str:	db	"U486DX2",0

	else	;No_Brand_For_UMCCPU

		Cpu_U5_Str:		db	"486SX",0
		Cpu_U486sx2_Str:	db	"486SX2",0
		Cpu_U486DX_Str:		db	"486DX",0
		Cpu_U486DX2_Str:	db	"486DX2",0

	endif	;No_Brand_For_UMCCPU

	;----- AMD 486 -----

	ifndef	No_Brand_For_AMDCPU

		Cpu_AMD486_Str:		db	"Am486DX",0
		Cpu_AMD486DX2_Str:	db	"Am486DX2",0
		Cpu_AMD486DX4_Str:	db	"Am486DX4",0
		Cpu_AMD486Plus_Str:	db	"Enhanced Am486DX2",0
		Cpu_AMD486DX4Plus_Str:	db	"Enhanced Am486DX4",0
		Cpu_AmdDX5_Str:		db	"Am5x86-P75",0
		Cpu_AmdDX5_160_Str:  	db	"Am5x86-P90",0
		Cpu_AmdDX5_150_Str:  	db	"Am5x86-P75+",0

	else	;No_Brand_For_AMDCPU

		Cpu_AMD486_Str:		db	"486DX",0
		Cpu_AMD486DX2_Str:
		Cpu_AMD486Plus_Str:	db	"486DX2",0
		Cpu_AMD486DX4_Str:
		Cpu_AMD486DX4Plus_Str:	db	"486DX4",0
		Cpu_AmdDX5_Str:		db	"Am5x86-P75",0
		Cpu_AmdDX5_160_Str:  	db	"Am5x86-P90",0
		Cpu_AmdDX5_150_Str:  	db	"Am5x86-P75+",0

	endif	;No_Brand_For_AMDCPU

ELSE	;BIOS_SUPPORT_486

	Cpu_AmdDX5_Str:
	cpu_486dx_str:
	cpu_486sx_str:
	cpu_487sx_str:
	cpu_486sx2_str:
	cpu_486dx2_str:
	Cpu_P24t_str:
	Cpu_P24c_Str:
	Cpu_P24D_Str:
	Cpu_AMD486Plus_Str:
	Cpu_AMD486DX4Plus_Str:
	Cpu_U486sx2_Str:
	Cpu_U486DX_Str:
	Cpu_U486DX2_Str:
	Cpu_M9_Str:
	TI_486dx2_str:
	Cpu_Cyrix_Dx4_Str:
	Cpu_486s_Str:
	Cpu_486s2_Str:
	Cpu_M7_Str:
	Cpu_M7_2_Str:
	Cpu_AMD486_Str:
	Cpu_U5_Str:
	Cpu_AMD486DX2_Str:
	Cpu_AMD486DX4_Str:	db	0

ENDIF	;BIOS_SUPPORT_486

;-------------------------- 586 CPU Strings --------------------------

	Cpu_AmdD5K86_Str:
	Cpu_586_Str:
	Cpu_P54c_Str:
	Cpu_M1_Str:

	Cpu_CyrixGXm_Str	db	"Cyrix MediaGX With MMX",0

;-------------------------- 686 CPU Strings --------------------------

	Cpu_P6_Str:		db	0

;-------------------------- IBM CPU Strings --------------------------

IF	BIOS_SUPPORT_IBM_CPU

	cpu_ibm386slc_str:	db	"IBM386SLC",0
	cpu_ibm486slc2_str:	db	"IBM486SLC2",0
	cpu_ibm486dlc3_str:	db	"IBM486DLC3",0

ELSE	;BIOS_SUPPORT_IBM_CPU

	cpu_ibm386slc_str:
	cpu_ibm486slc2_str:
	cpu_ibm486dlc3_str:	db	0

ENDIF	;BIOS_SUPPORT_IBM_CPU

;-------------------------- TI CPU Strings --------------------------

IF	BIOS_SUPPORT_TI_CPU

	Cpu_TI486SXL_Str:	db	"TI486SXL",0
	Cpu_TI486SXL2_Str:	db	"TI486SXL2",0
	Cpu_TI486SXLC_Str:	db	"TI486SXLC",0
	Cpu_TI486SXLC2_Str:	db	"TI486SXLC2",0

ELSE	;BIOS_SUPPORT_TI_CPU

	Cpu_TI486SXL_Str:
	Cpu_TI486SXL2_Str:
	Cpu_TI486SXLC_Str:
	Cpu_TI486SXLC2_Str:	db	0

ENDIF	;BIOS_SUPPORT_TI_CPU

;---------------------- Dummy/Unknown CPU Strings -------------------

	unknown_str:		db	"Unknown"
	Cpu_486dxS_Str:
	Cpu_486sxS_Str:
	Cpu_486dx2S_Str:
				db	0

;[]=================================================================[]
;Procedure   :	Disp_Extra_CPU_Info
;Input	     :	None
;Ouput	     :	None
;Description :	If CPU Type:
;
;		. PENTIUM PRO & PENTIUM
;
;		   IF   ODP CPU show 'ODP-S' on screen
;		   IF   MMX CPU show 'MMX' on screen
;		   IF   ODP-MMX CPU show 'ODP-MMX' on screen
;		   ELSE show '-S' on screen to indicate SMI
;
;		. Cyrix 6x86L CPU
;
;		  Append a 'L' to '6x86'
;
;		. Other CPUs
;
;		  show '-S' on screen to indicate SMI
;
;[]=================================================================[]
		public	Disp_Extra_CPU_Info
Disp_Extra_CPU_Info	Proc	Near

;---------------------------------------------------------------
; Display CPU type as "6x86L" if the revision number is 20h-2fh,
; regular 6x86 is 00h-1fh
;---------------------------------------------------------------

;---------------------------------------------------------------
; Show -MMX & -ODP for all 586 or above CPU
;---------------------------------------------------------------

;-------------------------------------------------------
;Try to skip '-S' for all AMD & Cyrix 586 level CPU
;-------------------------------------------------------

;-------------------------------------------------------
; This is for special customer
; If the CPU is Cyrix then don't show S-serial
;-------------------------------------------------------
IF	BIOS_SUPPORT_486
	ifdef	No_Cyrix_Mark_For_M6M7
		F000_Call Cyrix_Detect
		jnc	Disp_S_CPU_Exit
	endif	;No_Cyrix_Mark_For_M6M7
ENDIF	;BIOS_SUPPORT_486

;-------------------------------------------------------
; Display '-S' on screen
;-------------------------------------------------------
ifdef	PM_SUPPORT
		test	byte ptr OVERRIDE[BP],(SMICPU shr 8)
		jz	No_S
		mov	al,"-"
		call	F000_Display_Char
		mov	al,"S"
		call	F000_Display_Char
No_S:
endif	;PM_SUPPORT

Disp_S_CPU_Exit:

		ret

Disp_Extra_CPU_Info	Endp

;;;;; _2_Str		db	'2', 0
;;;;; _3_Str		db	'3', 0
;;;;; _C6_Str		db	'C6', 0

;;;;;;Function : Read CPU ID
;;;;;;Input    : none
;;;;;;Output   : EAX - CPU ID information
;;;;;;	    EDX - CPU features
;;;;;		Public	fPROC_Read_CpuID
;;;;;fPROC_Read_CpuID	PROC	FAR
;;;;;		call	Read_CpuID
;;;;;		ret
;;;;;fPROC_Read_CpuID	ENDP
;;;;;		Public	Read_CpuID
;;;;;Read_CpuID	proc	near
;;;;;		push	ebx
;;;;;		mov	eax,1			;read cache isze
;;;;;		db	0Fh,0A2h		;OP code: CPUID
;;;;;		pop	ebx
;;;;;		ret
;;;;;Read_CpuID	endp

;;;;;;[]--------------------------------[]
;;;;;;Input	:	None
;;;;;;Ouput	:	ZF - Cyrix M2
;;;;;;		NZ - not Cyrix M2
;;;;;;[]--------------------------------[]
;;;;;		public	fPROC_Check_M2Cpu
;;;;;fPROC_Check_M2Cpu	PROC	FAR
;;;;;		call	Check_M2Cpu
;;;;;		ret
;;;;;fPROC_Check_M2Cpu	ENDP
;;;;;		public	Check_M2Cpu
;;;;;Check_M2Cpu	proc	near
;;;;;		push	ax
;;;;;		mov	al,0feH			;DIR1 register
;;;;;		out	22h,al
;;;;;		in	al,23h			;read DIR1 value
;;;;;		cmp	al,51h
;;;;;		jb	Not_M2Cpu
;;;;;		cmp	al,5fh
;;;;;		ja	Not_M2Cpu
;;;;;		xor	al,al			;return zero flag
;;;;;Not_M2Cpu:
;;;;;		pop	ax
;;;;;		ret
;;;;;Check_M2Cpu	endp

;;;;;;--------------------------------------------------------------------
;;;;;;Output : CF = 0  - Cyrix MII CPU
;;;;;;	  CF = 1  - Not Cyrix MII CPU
;;;;;;--------------------------------------------------------------------
;;;;;		Public	fPROC_Check_MII_CPU
;;;;;fPROC_Check_MII_CPU	PROC	FAR
;;;;;		call	Check_MII_CPU
;;;;;		ret
;;;;;fPROC_Check_MII_CPU	ENDP
;;;;;		Public	Check_MII_CPU
;;;;;Check_MII_CPU	proc	near
;;;;;
;;;;;		call	Check_M2Cpu
;;;;;		jne	Not_Cyrix_MII
;;;;;
;;;;;		mov	al, 0FFh		;DIR1 register
;;;;;		out	22h, al
;;;;;		in	al, 23h			;read DIR1 value
;;;;;		cmp	al,08h			; 08h or greater is MII
;;;;;		jb	Not_Cyrix_MII	; No
;;;;;
;;;;;		clc
;;;;;		ret
;;;;;Not_Cyrix_MII:
;;;;;
;;;;;		stc
;;;;;		ret
;;;;;
;;;;;Check_MII_CPU	endp

;;;;;;[]--------------------------------[]
;;;;;;Input	:	None
;;;;;;Ouput	:	ZF - Cyrix 6x86
;;;;;;		NZ - not Cyrix 6x86
;;;;;;[]--------------------------------[]
;;;;;
;;;;;		public	fPROC_Check_M1_Cpu
;;;;;fPROC_Check_M1_Cpu	PROC	FAR
;;;;;		call	Check_M1_Cpu
;;;;;		ret
;;;;;fPROC_Check_M1_Cpu	ENDP
;;;;;		public	Check_M1_Cpu
;;;;;Check_M1_Cpu	proc	near
;;;;;		cmp	sp, 0FFFFh	;always return not M1
;;;;;		ret
;;;;;Check_M1_Cpu	endp

;;;;;;[]--------------------------------[]
;;;;;;Input	:	None
;;;;;;Ouput	:	ZF - K5 or K6
;;;;;;		NZ - not K5, not K6
;;;;;;[]--------------------------------[]
;;;;;
;;;;;		public	fPROC_Check_K586_Cpu
;;;;;fPROC_Check_K586_Cpu	PROC	FAR
;;;;;		call	Check_K586_Cpu
;;;;;		ret
;;;;;fPROC_Check_K586_Cpu	ENDP
;;;;;		Public	Check_K586_Cpu
;;;;;Check_K586_Cpu	proc	near
;;;;;		cmp	sp, 0FFFFh	;always return NOT K6
;;;;;		ret
;;;;;Check_K586_Cpu	endp

;;;;;;[]-------------------------[]
;;;;;;Input	:	None
;;;;;;Ouput	:	ZF - K6
;;;;;;		NZ - not K6
;;;;;;[]-------------------------[]
;;;;;		public	fPROC_Check_K6_Cpu
;;;;;fPROC_Check_K6_Cpu	PROC	FAR
;;;;;		call	Check_K6_Cpu
;;;;;		ret
;;;;;fPROC_Check_K6_Cpu	ENDP
;;;;;		Public	Check_K6_CPU
;;;;;Check_K6_CPU	Proc	Near
;;;;;		cmp	sp, 0FFFFh		;always return NOT K6
;;;;;		ret
;;;;;Check_K6_CPU	Endp

;;;;;;[]------------------------------------------------------[]
;;;;;;Function: Return proper CPU string for K6 series CPU
;;;;;;Input	 : None
;;;;;;Output  : SI - offset of CPU string to display
;;;;;;Note    : "AMD-K6(tm)/xxx"   for 056x & 057x
;;;;;;	   "AMD-K6(tm)-2/xxx" for 058x
;;;;;;	   "AMD-K6(tm)-3/xxx" for 059x
;;;;;;[]------------------------------------------------------[]
;;;;;TreatK6String	proc	near
;;;;;		ret
;;;;;TreatK6String	endp

;[]=================================================================[]
;Input	:	DI = 1 --> show P-Rating with '-'
;		DI = 0 --> show P-Rating without '-'
;
;Output	:	NC - Show P-Rating successfully
;		CF - Show P-Rating not successful
;[]=================================================================[]
		Public	Try_Show_PRating
Try_Show_PRating	Proc	Near
		stc		;defaut no show P-Rating
		ret
Try_Show_PRating	Endp

;Function : Program USWC for P6-class CPU according user's CMOS select
;Input    : none
;Output   : none
		public	Prg_P6_USWC
Prg_P6_USWC	proc	near
		ret
Prg_P6_USWC	endp

ECODE		ENDS

XGROUP		GROUP	XCODE
XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP, ES:XGROUP

XCODE		ENDS

ENDIF	;COMPILE_FOR_E0
