;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R04	04/12/99 MCH	Added the define of "ICS24881_Need_Freq_Cntl" for
;			defining "ICS24881_Freq_Cntl" & "ICS24881_Use_Clk_Cntl"
;			can both work and vaild of routine "Auto_Detect_Clock".
;R03A	04/01/99 AVN	Fixed coding error and VUMA.ASM SDRAM clock report fail.
;R03	03/22/99 AVN	Fixed coding error and VUMA.ASM SDRAM clock report fail.
;R02	02/11/99 AVN	Added ICS 9248-81 support.
;			define 'Hardware_SMBus_Support'
;			define 'Auto_Detect_Async_Sync'
;			define 'Clockgen_SDRAM_Freq_CMOS'
;			define 'Clockgen_SDRAM_Freq_CMOS_Bits'
;R01	02/02/99 DRS	SIS suggests to do delay for I2C data read/write.But
;			it spends too much time in POST C1H. Take away,
;			function is still OK.
;R00	02/02/99 DRS	Initial version
;			This function depends on ICS24881_Support and
;			Auto_Detect_Async_Sync definitions. It is for reading
;			the clock generator internal hardware latched 
;			signal value.i.e. SD_SEL#, FS0#, FS1#, FS2#
;			GVC has special definition which is Only_Support_66_100.

;R04 - start
ifdef	ICS24881_Freq_Cntl
ICS24881_Need_Freq_Cntl		EQU	1
endif;	ICS24881_Freq_Cntl
ifdef	ICS24881_Use_Clk_Cntl
ICS24881_Need_Freq_Cntl		EQU	1
endif;	ICS24881_Use_Clk_Cntl
;R04 - end

ifdef	ICS24881_Support
ifdef	Auto_Detect_Async_Sync
;R02 - start
ifdef	Hardware_SMBus_Support
ifdef	SiS5595_BVersion
;R04ifdef	ICS24881_Freq_Cntl
ifdef	ICS24881_Need_Freq_Cntl				;R04
Auto_Detect_Clock	proc	near

	;; Read Clock From ClockGen
	;; Set SMBus Address
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,04h
		out	dx,al
		NEWIODELAY

		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		mov	al,0D3h
		out	dx,al
		NEWIODELAY

	;; Set SMBus Command
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,05h
		out	dx,al
		NEWIODELAY

		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		mov	al,00h
		out	dx,al
		NEWIODELAY

	;; Set SMBus 1 Byte Count
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,07h
		out	dx,al
		NEWIODELAY

		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		mov	al,01h
		out	dx,al
		NEWIODELAY

	;; Read Block Data
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,02h
		out	dx,al
		NEWIODELAY

		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		mov	al,1ah
		out	dx,al
		NEWIODELAY

	;; Wait ACK
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,00h
		out	dx,al
		NEWIODELAY

Wait_SMBus_Read_ACK1:
		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		in	al,dx
		NEWIODELAY
		test	al,40h
		jz	short Wait_SMBus_Read_ACK1
		out	dx,al
		NEWIODELAY

	;; Read Data From SMBus Buffer
		mov	dx,ACPI_BASE_IO_ADDR+38h	;SMBus IO index
		mov	al,08h
		out	dx,al
		NEWIODELAY

		mov	dx,ACPI_BASE_IO_ADDR+39h	;SMBus IO data
		in	al,dx
		NEWIODELAY

	;; Check ClockGen Frequence Control Bit
		test	al,08h
		jz	short CoolBoot_And_InsKey_Press

	;; Write SDRAM clock to CMOS
		and	al,74h
		mov	dl,al				;Save clock val
		xor	si,si

Scan_Next_SDRAM_Freq:
		cmp	al,byte ptr CS:[SDRAM_CLOCK_FREQ_TBL+SI]
		je	short Write_SDRAM_Freq_To_CMOS

		cmp	byte ptr CS:[SDRAM_CLOCK_FREQ_TBL+SI],0ffh
		je	short SDRAM_Clock_Val_Fail

		inc	si
		inc	si
		jmp	short Scan_Next_SDRAM_Freq

Write_SDRAM_Freq_To_CMOS:
		mov	bl,byte ptr CS:[SDRAM_CLOCK_FREQ_TBL+SI+1]
		mov	al,Clockgen_SDRAM_Freq_CMOS_Bits
@@:
		shr	al,1
		jc	short @f
;R03		shl	bl,1
;R03A		shr	bl,1				;R03
		shl	bl,1				;R03A
		jmp	short @b

@@:
		mov	al,Clockgen_SDRAM_Freq_CMOS
		out	70h,al
		NEWIODELAY
		in	al,71h
		NEWIODELAY
		and	al,not Clockgen_SDRAM_Freq_CMOS_Bits
		or	al,bl
		out	71h,al
		NEWIODELAY
SDRAM_Clock_Val_Fail:

		xor	bl,bl				;Set sync mode
		mov	al,dl				;Load clock val
		test	al,04h
		jnz	short Set_SDRAM_Asyn_Syn_Mode

	;; System Clock Is ASyn Mode
		mov	bl,03h				;Async and CPU < SDRAM
		cmp	al,10h
		je	short Set_SDRAM_Asyn_Syn_Mode

		mov	bl,01h				;Async and CPU > SDRAM

Set_SDRAM_Asyn_Syn_Mode:
	;; Set SDRAM in Asyn Mode First
		mov	cx,(SIS620_ID)+8Eh
		ROM_CALL Get_Ct
		and	al,not 03h
		or	al,bl
		ROM_CALL Set_Ct

CoolBoot_And_InsKey_Press:
		jmp	Auto_Dectect_Clock_RTN
Auto_Detect_Clock	endp

SDRAM_CLOCK_FREQ_TBL:
ifdef	Release_Asyn_SDRAM_Freq
		db	01110000b, 00000010b		;133/88 MHz
		db	01100000b, 00000010b		;124/82 MHz
		db	01010000b, 00000001b		;112/74 MHz
		db	01000000b, 00000001b		;100/75 MHz
		db	00110000b, 00000000b		;100/66 MHz
		db	00100000b, 00000000b		;95/63 MHz
		db	00000000b, 00000011b		;90/90 MHz
		db	00010000b, 00000011b		;66/100 MHz
endif;	Release_Asyn_SDRAM_Freq
		db	00100100b, 00000010b		;83/83 MHz
		db	00000100b, 00000000b		;66/66 MHz
		db	00010100b, 00000001b		;75/75 MHz
		db	00110100b, 00000011b		;95/95 MHz
		db	01000100b, 00000011b		;100/100MHz
		db	01010100b, 00000011b		;112/112MHz
		db	01100100b, 00000011b		;124/124MHz
		db	01110100b, 00000011b		;133/133MHz
		db	-1				;Fail
		
;R04endif;	ICS24881_Freq_Cntl
endif;	ICS24881_Need_Freq_Cntl				;R04
endif;	SiS5595_BVersion
else;	Hardware_SMBus_Support
;R02 - end

SDA             EQU     10h	;I2C Data 
SCL             EQU     08h	;I2C Clock
I2CBusControl	EQU	04h	;R14

;;;;;;;;;;;;;;;;;;;;;;;;And		Or
Set_Start_Tbl:	db	0FFh		,SCL+SDA+I2CBusControl
		db	Not SDA		,00h
		db	Not SCL		,00h
		db	55h		,0AAh
		
Wait_ACK_Tbl:
		db	0FFh		,SDA
		db	0FFh		,SCL
		db	Not SCL		,00h
		db	55h		,0AAh

Set_NoACK_Tbl:	db	Not SCL		,00
		db	0FFh		,SDA
		db	0FFh		,SCL	
		db	Not SCL		,00h
		db	55h		,0AAh

Set_Stop_Tbl:	db	Not SDA		,SCL
		db	0FFh		,SDA
		db	55h		,0AAh

Auto_Detect_Clock	proc	near
		ror	edi,16				;store return address

		;
		; Set_Start
		;
		mov	ax,cs
		mov	ds,ax
		mov	si,offset cs:Set_Start_Tbl

	Set_Start_Loop:
		cmp	byte ptr ds:[si],55h		; Value valid ?
		jne	short @f			; yes
		cmp	byte ptr ds:[si+1],0AAh
		je	short Set_Start_Loop_Exit	;End
	@@:
		mov	cx,(SIS5595_ID+6Dh)
		ROM_CALL Get_Ct
		and	al,byte ptr ds:[si]
		or	al,byte ptr ds:[si+1]
		ROM_CALL Set_Ct
;R01		NEWIODELAY
;R01		NEWIODELAY
		NEWIODELAY
		add	si,2
		jmp	short Set_Start_Loop
Set_Start_Loop_Exit:
		;
		; Wr_Byte : Device ID = 0D3h
		;
        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		and	al,NOT SCL
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time1			;;;Delay 1FFhx2 jmp$+2

		mov	si,8
		mov	dl,0D3h
	Wr_Bits:
		ROM_CALL Delay_Time1			;;;Delay
		xor	dh,dh
		shl	dx,1				; shift 1 bit to dh
		shl	dh,4				; SDA	
		mov	di,dx				;;;; Store DX
        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		and	al,NOT SDA
		mov	dx,di				;;;; Re-Store DX
		or	al,dh
		mov	di,dx  				;;;; Store DX
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time1			;Delay

		mov	cx,(SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		or	al,SCL		
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time1			;Delay
		
		mov	cx,(SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		and	al,NOT SCL
		ROM_CALL Set_Ct
		mov	dx,di
		sub	si,1
		cmp	si,0
		jne	short Wr_Bits

		;
		; Wait_ACK
		;
		mov	si,offset cs:Wait_ACK_Tbl
Wait_ACK_Loop:
		mov	cx,(SIS5595_ID+6Dh)
		cmp	byte ptr ds:[si],55h		; Value valid ?
		jne	short @f			; yes
		cmp	byte ptr ds:[si+1],0AAh
		je	short Wait_ACK_Loop_Exit	;End
	@@:
		ROM_CALL Get_Ct
		and	al,byte ptr ds:[si]
		or	al,byte ptr ds:[si+1]
		ROM_CALL Set_Ct
;R01		NEWIODELAY
;R01		NEWIODELAY
		NEWIODELAY
		add	si,2
		jmp	short Wait_ACK_Loop
Wait_ACK_Loop_Exit:

		;
		; Rd_Data
		;
		mov	di,offset cs:Rd_Data_10
		jmp	Jump_Rd_Data
Rd_Data_10:

		ror	esi,16
		mov	bx,si
		xor	bh,bh			;####
		ror	ebx,16				;;;;;;Store

		;
		; Set_NoACK
		;
		mov	di,offset cs:Set_NoACK_10
		jmp	Jump_Set_NoACK
Set_NoACK_10:

		;ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
		ror	ebx,16				;;;;;;Re-Store
Receive_Buffer:
		ror	ebx,16				;;;;;;Store
		mov	di,offset cs:Rd_Data_RTN20
		jmp	Jump_Rd_Data			; call
	Rd_Data_RTN20:

		mov	di,offset cs:Set_NoACK_20
		jmp	Jump_Set_NoACK
	Set_NoACK_20:

		ror	ebx,16
ifdef	Only_Support_66_100
		cmp	bx,05h				;Byte1 ??
		je	short BX_Is_Byte1		;yes
		cmp	bx,04h				;Byte2 ??
		jne     short Next_Receive_Buffer	;no

BX_Is_Byte2:
		ror 	esi,16
		mov 	ax,si
		test	al,10000000b		; CPU < SDRAM ?
		jnz	short Set_Stop		;yes

	CPU_Higher_SDRAM:			
		mov	cx,(SIS620_ID)+51h	; SIS suggest
		ROM_CALL Get_Ct			
		and	al,NOT 01h
		ROM_CALL Set_Ct			

		mov	cx,(SIS620_ID+8Eh)	
		ROM_CALL Get_Ct			
		and	al,NOT 00000010b
		ROM_CALL Set_Ct
		jmp 	short Set_Stop

		;--------------------------------
BX_Is_Byte1:
		ror 	esi,16
		mov 	ax,si
		test	al,00000001b			;Async
		jz	short Next_Receive_Buffer	;yes
	_Sync:
		mov	cx,(SIS620_ID+8Eh)
		ROM_CALL Get_Ct
		and	al,NOT 00000011b
		ROM_CALL Set_Ct
		jmp	short Set_Stop
endif	;Only_Support_66_100

Next_Receive_Buffer:
		sub	bx,1
		cmp	bx,0
		jne	short Receive_Buffer

		;
		; Set_Stop
		;
Set_Stop:
		mov	si,offset cs:Set_Stop_Tbl
Set_Stop_Loop:
		mov	cx,(SIS5595_ID+6Dh)
		cmp	byte ptr ds:[si],55h		; Value valid ?
		jne	short @f			; yes
		cmp	byte ptr ds:[si+1],0AAh
		je	short Set_Stop_Loop_Exit	;End
	@@:
		ROM_CALL Get_Ct
		and	al,byte ptr ds:[si]
		or	al,byte ptr ds:[si+1]
		ROM_CALL Set_Ct
;R01		NEWIODELAY
;R01		NEWIODELAY
		NEWIODELAY
		add	si,2
		jmp	short Set_Stop_Loop
Set_Stop_Loop_Exit:
;----------------------------------------------------------
		ror	edi,16				;Restore return address
		jmp	di

Auto_Detect_Clock	endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Direct Jump Part
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Function : Read one byte data from I2C
; Output   : ESI xxXXxxxx (hex) -- valid value is XX
; Note     : Don't destory Register DI value
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Jump_Rd_Data	proc	near

        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		and	al,NOT SCL
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time2			;;;Delay 300h NEWIODELAY

		xor	esi,esi
		mov	si,8
	Rd_Bits:
		ror	esi,16			
		ROM_CALL Delay_Time3			;;;Delay 08h NEWIODELAY
        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
        	or	al, SDA			
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time2			;;;Delay 300h NEWIODELAY
		
        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
        	or	al, SCL			
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time2			;;;Delay 300h NEWIODELAY
		ROM_CALL Delay_Time3			;;;Delay 08h NEWIODELAY

        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Get_Ct
		mov	ah,al				;store al
		and	al, SDA				;Mask
		shr	al,4
		shl	si,1
		or	si,ax				
		mov	al,ah				;restore al
		and	al,NOT SCL
        	mov	cx, (SIS5595_ID + 6Dh)
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time2			;;;Delay 300h NEWIODELAY
		ror	esi,16				
		sub	si,1
		cmp	si,0
		jne	Rd_Bits

		ROM_CALL Delay_Time3			;;;Delay 08h NEWIODELAY
		jmp	di

Jump_Rd_Data	endp

;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; Function : Read one byte data from I2C
; Output   : ESI higher 16bits
; Note     : Don't destory Register DI value
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Jump_Set_NoACK	proc	near

		mov	si,offset cs:Set_NoACK_Tbl
	Set_NoACK_Loop:
		mov	cx, (SIS5595_ID + 6Dh)
		cmp	byte ptr ds:[si],55h		; Value valid ?
		jne	short @f			; yes
		cmp	byte ptr ds:[si+1],0AAh
		je	short Set_NoACK_Loop_Exit	;End
	@@:
		ROM_CALL Get_Ct
		and	al,byte ptr ds:[si]
		or	al,byte ptr ds:[si+1]
		ROM_CALL Set_Ct
		ROM_CALL Delay_Time2
		add	si,2
		jmp	short Set_NoACK_Loop
Set_NoACK_Loop_Exit:
		jmp	di

Jump_Set_NoACK	endp
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
; ROM Call Part
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Delay_Time1	proc	near
		mov	cx,01FFh
	@@:
;R01		jmp	$+2
;R01		jmp	$+2
		loop	@b
	   	ret
Delay_Time1	endp

Delay_Time2	proc	near
		mov	cx,300h
	@@:
;R01		NEWIODELAY
		loop	@b
	   	ret
Delay_Time2	endp

Delay_Time3	proc	near
		mov	cx,08h
	@@:
;R01		NEWIODELAY
		loop	@b
	   	ret
Delay_Time3	endp
endif	;Hardware_SMBus_Support				;R02
endif	;Auto_Detect_Async_Sync
endif	;ICS24881_Support
