;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R44	03/20/98  RCH	Store the desired item value into CMOS and program
;			register with CMOS value instead of taking BIOS 
;			default while the item is disabled if switch
;			"LOAD_CMOS_FOR_ITEMDISABLE" is used.
;R43	02/24/98  RAY	Invalidate the ITEMSTAT=SPECIALPRG
;			note: See also BSETUP.INC
;R42	10/07/97  RAY	1. Clean all Rxx
;			2. Move code to XGROUP to save F000 code area.

.386

.XLIST
		INCLUDE	BIOS.CFG
		INCLUDE	COMMON.MAC
		INCLUDE COMMON.EQU

		INCLUDE	POST.EQU
		INCLUDE POST.MAC

		extrn	Rom_Table:near
		extrn	EndRom_Table:near
		extrn	PageOffset:near
		extrn	Get_Ct:near
		extrn	Set_Ct:near
		extrn	Auto_Table:near
		extrn	EndAuto_Table:near

		extrn	Ct_ReTable_Auto:near
		extrn	Mask_To_Mask_Trans:near

ifdef	PM_SUPPORT
		extrn	Get_PMU:near
		extrn	Set_PMU:near
		extrn	PM_Feature_START:near
		extrn	PM_Page_Offset:near
		extrn	PM_Option_Check:near
		extrn	PM_Auto_Table:near
endif	;PM_SUPPORT

ifdef	New_Auto_Table_Method
		extrn	New_Auto_Table:Near
endif	;New_Auto_Table_Method

;R43		extrn	Cf_Special_Prg:near	;subroutine in cfeature.asm
		extrn	Ct_Auto_Check:near
		extrn	F000_CALL_PROC:near

.LIST
G_RAM		SEGMENT	USE16 AT 0

		ORG	04H*4
		INCLUDE	SEG_0.INC

		ORG	400H
		INCLUDE	G_RAM.INC

G_RAM		ENDS

DGROUP		GROUP	FCODE

FCODE		SEGMENT	USE16 PARA PUBLIC 'CODE'
		ASSUME	CS:DGROUP, DS:DGROUP

;[]--------------------------------------------------------------------[]
;output	:	SI point to auto-table according to system clock
;		& CPU clock type (2x, 3x...)
;[]--------------------------------------------------------------------[]
		Public	Get_Auto_Table_Offset
Get_Auto_Table_Offset	Proc	Near

ifdef	New_Auto_Table_Method

		push	cx
		push	ds

		mov	ax, G_RAM
		mov	ds, ax
		mov	si, offset CPU_CLOCK
		mov	al, ds:[si]
		and	al, CPU_CLOCK_MASK
		xor	ah, ah
		sub	al, CPU50
		shr	ax, 3

		mov	si, (offset New_Auto_Table) + 1
		add	si, ax

		call	Ct_ReTable_Auto

		mov	si, cs:[si]		;si point to auto cfg data

		pop	ds
		pop	cx

		ret

else	;New_Auto_Table_Method

		push	cx

		push	ds
		mov	ax, G_RAM
		mov	ds, ax
		assume	ds:G_RAM
		mov	al, ds:[CPU_CLOCK]
		xor	ah, ah

		cmp	al, CPU66
		jbe	short @F
		mov	al, CPU66
	@@:
		cmp	byte ptr CPU_LEVEL[bp], LEVEL_586
		jae	short OneClk

		test	byte ptr OVERRIDE[bp], (FOURCLOCK SHR 8)
		jnz	short Yes_MxClock

		test	byte ptr OVERRIDE[bp], DOUBLE_CLOCK+THREE_CLOCK
		jz	short OneClk
Yes_MxClock:
      		cmp	al, CPU25
      		jae	short @F

		mov	al, CPU25
@@:
		sub	al, CPU20		;DX2 must start from 25Mhz
OneClk:
		shr	ax, 3
		dec	ax
		dec	ax

		pop	ds
		assume	ds:DGROUP

		mov	si, offset cs:Auto_Table_List
		mov	dl, FIXED_DISK_STEP[bp]
		and	dl, not CPUCACHE+COPROCESSOR
		xor	dh, dh
		add	si, dx
		mov	si, cs:[si]

		push	ax
		call	Ct_ReTable_Auto
		pop	ax

		add	si, ax
		mov	si, cs:[si]		;si point to auto cfg data

		pop	cx

		ret

endif	;New_Auto_Table_Method

Get_Auto_Table_Offset	Endp

ifndef	New_Auto_Table_Method
		extrn	Auto_CPU_386DX:near
		extrn	Auto_CPU_386SX:near
		extrn	Auto_CPU_386SL:near
		extrn	Auto_CPU_486DX:near
		extrn	Auto_CPU_486SX:near
		extrn	Auto_CPU_486DX2:near
		extrn	Auto_CPU_486SLC:near
		extrn	Auto_CPU_486DLC:near
		extrn	Auto_CPU_IBM386SLC:near
		extrn	Auto_CPU_IBM486SLC2:near
		extrn	Auto_CPU_P24T:near
		extrn	Auto_CPU_486S:near
		extrn	Auto_CPU_486S2:near
		extrn	Auto_CPU_586:near
		extrn	Auto_CPU_486DXS:near
		extrn	Auto_CPU_486SXS:near
		extrn	Auto_CPU_486DX2S:near
		extrn	Auto_CPU_IBM486DLC3:near

		public	Auto_Table_List
		align	4
Auto_Table_List:
		dw	Auto_CPU_386DX
		dw	Auto_CPU_386SX
		dw	Auto_CPU_386SL
		dw	Auto_CPU_486DX
		dw	Auto_CPU_486SX
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_486SLC
		dw	Auto_CPU_486DLC
		dw	Auto_CPU_IBM386SLC
		dw	Auto_CPU_IBM486SLC2
		dw	Auto_CPU_P24T
		dw	Auto_CPU_486S
		dw	Auto_CPU_486S2
		dw	Auto_CPU_586
		dw	Auto_CPU_486DXS
		dw	Auto_CPU_486SXS
		dw	Auto_CPU_486DX2S
		dw	Auto_CPU_IBM486DLC3
		dw	Auto_CPU_486DX
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_IBM486DLC3
		dw	Auto_CPU_486DLC
		dw	Auto_CPU_IBM486SLC2
		dw	Auto_CPU_486DX
		dw	Auto_CPU_486DX
		dw	Auto_CPU_586
		dw	Auto_CPU_486SLC
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_IBM486DLC3

		dw	Auto_CPU_586
		dw	Auto_CPU_486DX2
		dw	Auto_CPU_IBM486DLC3

		dw	Auto_CPU_486DX2			;TYPE_U486SX2
		dw	Auto_CPU_486DX			;TYPE_U486DX
		dw	Auto_CPU_486DX2			;TYPE_U486DX2

ifndef	M9_USE_DX4_Table
		dw	Auto_CPU_486DX2
else	;M9_USE_DX4_Table
		dw	Auto_CPU_IBM486DLC3		;TYPE_M9
endif	;M9_USE_DX4_Table

		dw	Auto_CPU_IBM486DLC3
		dw	Auto_CPU_586

		dw	Auto_CPU_IBM486DLC3
		dw	Auto_CPU_586
endif	;New_Auto_Table_Method

FCODE		ENDS

XGROUP		GROUP	XCODE
XCODE		SEGMENT USE16 PARA PUBLIC 'XCODE'
		ASSUME	CS:XGROUP,ES:XGROUP

;[]===================================================================[]
;
; PRG_CHIPSET_DEFAULT:
;
;	Programs the chipset registers with default values. Flow:
;
;	1. Read ROM default registers, program them to chipset
;
; Entry: NONE
; Exit: NONE
;
; Saves: BP, SP, SS, FS, GS + NO STACK
;
; Author: Richard Chen
; Date: April 14, 1992
;
; Name	| Date		| Description
; -----------------------------------------------------------------
; TIM	| 11-Sep-1990   | Initial revision
;
;[]===================================================================[]
		ALIGN	4
		Public	fProc_Prg_Chipset_Default
fProc_Prg_Chipset_Default	Proc	Far

		push	ds

		mov	ax, SEG Rom_Table
		mov	ds, ax

;Program chipset with unselectable items

		mov	bx, offset Rom_Table
Prog_Next_Rom:
		cmp	bx, offset EndRom_Table
		je	short Rom_Table_Over

		mov	cx, [bx].RomReg		;get register index

	ifdef	PM_SUPPORT
		call	Decide_Ct_Or_PM
		F000_call ax
	else	;PM_SUPPORT
		F000_call Get_Ct		;read current value in AX/AL
	endif	;PM_SUPPORT

		mov	dx, [bx].RomRegMask
		not	dx
		and	ax, dx

		mov	dx, [bx].RomValue
		and	dx, [bx].RomRegMask
		or	ax, dx

		align	4

	ifdef	PM_SUPPORT
		F000_call di
	else	;PM_SUPPORT
		F000_call Set_Ct
	endif	;PM_SUPPORT

		add	bx, ROMITEM_SIZE
		jmp	short Prog_Next_Rom

Rom_Table_Over:

;Before memory sizing, we program chipset to default value

		mov	si, offset PageOffset

	Prog_Next_Page:

		lodsw
		cmp	ax, -1			;last page?
		je	short Finish_Rom_Def

		mov	bx, ax			;get first item
		lodsw
		mov	di, ax			;last item
		lodsw				;dumy load

	Prog_Next_Item:

		cmp	bx, di
		jae	short Prog_Next_Page

;R43		test	word ptr [bx].ItemStat, SPECIALPRG
;R43		jz	short Not_Special_Prg
;R43		F000_call Cf_Special_Prg
;R43		jc	short No_Program
;R43
;R43	Not_Special_Prg:

		call	Write_Default

	No_Program:

		add	bx, ITEM_SIZE
		jmp	short Prog_Next_Item

Finish_Rom_Def:

		pop	ds

		clc
		ret

fProc_Prg_Chipset_Default	Endp

		align	4
Write_Default	Proc	Near

		pusha
		mov	cx, [bx].CtReg		;get register index
		cmp	cx, -1
		je	short Not_Program

		align	4
	ifdef	PM_SUPPORT
		shl	edi, 16
		call	Decide_Ct_Or_PM
		F000_call ax
	else	;PM_SUPPORT
		F000_call Get_Ct		;read current value in AX/AL
	endif	;PM_SUPPORT

		mov	dx, [bx].CtRegMask
		not	dx
		and	ax, dx
		mov	dx, [bx].RomDefault
		and	dx, [bx].CtRegMask
		or	ax, dx

		align	4
	ifdef	PM_SUPPORT
	        F000_call di
		shr	edi, 16
	else	;PM_SUPPORT
		F000_call Set_Ct		;update register
	endif	;PM_SUPPORT

	Not_Program:

		popa
		ret

Write_Default	Endp

ifdef	PM_SUPPORT
;[]===================================================================[]
;Function:	decide Chipset or PM item
;Input	:	DS:BX point to menuitem or romitem
;output	:	if item is PM item:
;			AX = offset Get_PMU
;			DI = offset Set_PMU
;		else
;			AX = offset Get_Ct
;			DI = offset Set_Ct
;[]===================================================================[]
		align	4
Decide_Ct_Or_PM	Proc	Near

		mov	ax, offset Get_Ct
		mov	di, offset Set_Ct
		test	byte ptr [bx].RomStat, PMITEM
		jz	short Not_PM_Item
		mov	ax, offset Get_PMU
		mov	di, offset Set_PMU
Not_PM_Item:
		ret

Decide_Ct_Or_PM	Endp
endif	;PM_SUPPORT

;[]===================================================================[]
;
; PRG_CHIPSET:
;
;	Programs the chipset registers.
;
;	e.g.
;	     chipset reg. mask: 11010010b
;	             cmos mask: 00111100b
;
;	the corresponding bits in CMOS wlll be programmed to chipset
;	in the following manner:
;
;		  chipset reg.: 11001010b
;				\\  | /
;				 \\ |/
;			cmos  : 00111100b
;
; Entry: DI = 0 - normal programming
;	    = 1 - early programming
; Exit: NONE
;
; Saves: all
;
;[]===================================================================[]
		align	4
		Public	fProc_Prg_Chipset
fProc_Prg_Chipset	Proc	Far

		pusha
		push	ds
		push	es

		mov	ax, SEG PageOffset
		mov	ds, ax
		mov	si, offset PageOffset

	ifdef	PM_SUPPORT
		test	di, 02h				;if prg PM
		jz	short Prog_Next_Page_Value	;start from PM page
		mov	si, offset PM_Page_Offset
	endif	;PM_SUPPORT

	Prog_Next_Page_Value:

		lodsw
		cmp	ax, -1				;last page?
		je	Finish_Setup_Value

		mov	bx, ax				;get first item
		lodsw
		mov	es, ax				;last item
		lodsw					;dumy load

	ifdef	PM_SUPPORT
		test	di, 02h				;if prg chipset
		jnz	short @F			;  skip programming
		cmp	bx, offset PM_Feature_START	;  page pfeature!
		je	short Prog_Next_Page_Value
	@@:
	endif	;PM_SUPPORT

		jmp	Check_Page_End

	Prog_Next_Value:

		test	di, 1			;early prgoramming?
		jz	short Normal_Program

		test	word ptr [bx].ItemStat, EARLYPROG
		jz	Not_Reg
ifndef	LOAD_CMOS_FOR_ITEMDISABLE			   ;R44
		test	word ptr [bx].ItemStat, ITEMDISABLE
		jnz	short Default_Reg
endif;	LOAD_CMOS_FOR_ITEMDISABLE			   ;R44
		jmp	short Out_Reg

	Default_Reg:

		call	Write_Default
		jmp	Not_Reg

	Normal_Program:

		test	word ptr [bx].ItemStat, EARLYPROG
		jnz	short Not_Reg
ifndef	LOAD_CMOS_FOR_ITEMDISABLE			   ;R44
		test	word ptr [bx].ItemStat, ITEMDISABLE
		jnz	short Default_Reg
endif;	LOAD_CMOS_FOR_ITEMDISABLE			   ;R44

		test	word ptr [bx].ItemStat, AUTOPROG
		jz	short Out_Reg
		push	si
		push	bx

	ifdef	PM_SUPPORT
		test	word ptr [bx].ItemStat, PMITEM
		jz	short Check_Auto_Ct
		F000_call PM_Option_Check
		jmp	short End_Auto

	Check_Auto_Ct:
	endif	;PM_SUPPORT

		F000_call Ct_Auto_Check

	End_Auto:

		pop	bx
		pop	si
		jnz	short Not_Reg

	Out_Reg:

		mov	cx, [bx].CtReg		;get register index
		cmp	cx, -1
		je	short Not_Reg

		pusha
		push	cx
		mov	al, [bx].CmosLoc
		xor	ah, ah
		mov	si, ax
		mov	ax, [bp+si]
		mov	si, [bx].CmosMask
		mov	di, [bx].CtRegMask
		F000_call Mask_To_Mask_Trans
		mov	dx, ax
		pop	cx

		push	dx

	ifdef	PM_SUPPORT
		call	Decide_Ct_Or_PM
		F000_call ax
	else	;PM_SUPPORT
		F000_call Get_Ct
	endif	;PM_SUPPORT

		pop	dx

		mov	bx, [bx].CtRegMask
		not	bx
		and	ax, bx
		or	ax, dx

	ifdef	PM_SUPPORT
		F000_call di
	else	;PM_SUPPORT
		F000_call Set_Ct
	endif	;PM_SUPPORT

		popa

	Not_Reg:

		add	bx, ITEM_SIZE

	Check_Page_End:

		mov	ax, es
		cmp	bx, ax
		jb	Prog_Next_Value

	ifdef	PM_SUPPORT
		test	di, 02h				;if it is prg PM
		jnz	short Finish_Setup_Value	;do only one page!
	endif	;PM_SUPPORT

		jmp	Prog_Next_Page_Value

	Finish_Setup_Value:

		pop	es
		pop	ds
		popa

		clc
		ret

fProc_Prg_Chipset	Endp

ifdef	PM_SUPPORT
		align	4
		Public	fProc_Auto_Prg_PM
fProc_Auto_Prg_PM	Proc	Far

		pusha
		push	ds

		F000_call PM_Option_Check
		jz	short No_Auto_Item

		mov	ax, SEG PM_Auto_Table
		mov	ds, ax

		mov	di, offset PM_Auto_Table
		mov	cl, [di]
		xor	ch, ch
		jmp	short Prog_Next_Auto

fProc_Auto_Prg_PM	Endp
endif	;PM_SUPPORT

;[]===================================================================[]
;
; Prg_Auto:
;
;	Programs the chipset registers with AUTO table.
;
; Entry: none
; Exit: NONE
; Saves: all but flag
; Note : 1. The programmer must create AUTO tables in CFEATURE.ASM
;	    according CPU clock
;[]===================================================================[]
		align	4
		Public	fProc_Prg_Auto
fProc_Prg_Auto	Proc	Far

		pusha
		push	ds

		mov	ax, SEG Auto_Table
		mov	ds, ax

		mov	si, offset Auto_Table
		lodsb				;item size
		movzx	cx, al
		or	cx, cx
		jz	short No_Auto_Item
		F000_call Get_Auto_Table_Offset

Prog_Next_Auto:

		push	cx

ifndef	No_Auto_Set_Timing_In_Auto_Table

		mov	cx, [si].RomReg		;get register index

	ifdef	PM_SUPPORT
		call	Decide_Ct_Or_PM
		F000_call ax
	else	;PM_SUPPORT
		F000_call Get_Ct		;read current value in AX/AL
	endif	;PM_SUPPORT

		mov	dx, [si].RomRegMask
		mov	bx, [si].RomValue
		and	bx, dx
		not	dx
		and	ax, dx
		or	ax, bx

	ifdef	PM_SUPPORT
		F000_call di
	else	;PM_SUPPORT
		F000_call Set_Ct
	endif	;PM_SUPPORT

		add	si, ROMITEM_SIZE

endif;	No_Auto_Set_Timing_In_Auto_Table

		pop	cx
		loop	short Prog_Next_Auto
No_Auto_Item:
		pop	ds
		popa
		clc
		ret

fProc_Prg_Auto	Endp

XCODE		ENDS

		END

