;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R13	01/28/99 BAR	Support update ESCD DMI in SMM mode.
;			define switch "Flash_IN_SMBASE"
;R12	05/08/98 KEN	Modified some codes to correspond to the ESCDCHIP
;			modification that using flat mode to update flash
;			ROM.(i.e. Don't destroy any segment registers at
;			flash ROM reading/writing routines.)
;R11A	12/24/96 AVN	More Safely And Save More Code.
;R11	12/20/96 AVN	Fixed if Turn Off Power During Upadte DMI, EEPROM is
;			in Unprotection Mode, And Next Power On Will Lost
;			Data Some Time.
;R10	12/05/96 AVN	Suppost Auto Detect EEPROM ID at POST 6 For 1M EEPROM
;			and Save Code.
;R09	11/14/96 AVN	Fixed Pass for AMIDIAG.EXE PnP BIOS test.
;R08	03/27/96 AVN	Added ATMEL 29C010A FlashROM Support, And if do MXIC
;			FlashROM R/W test Will Effect ATMEL Program, So We
;			Enable Software Data Protection First For End ATMEL
;			ROM Cycle. (ATMEL program/erase same as SST FlashROM)
;R07	02/01/96 RAY	Fix coding mistake
;R05B	01/15/96 KEN	Restore original codes.
;R06	01/12/96 RAY	Should compare the whole block instead of just
;			comparing 1 byte while programming the flash.
;			This will cause the procedure always report successful
;			and thus the BIOS will not work on Intel Flash
;R05A	01/12/96 RCH	More modifies for 4GB access for P6 BIOS
;R05	01/12/96 KEN	Support updating ESCD with high memory (below 4GB).
;R04	12/09/11 RCH	P6 don't have 16bytes buffer , so change method for
;			supporting PnP/ESCD.
;R03	12/09/95 RAY	Support more than one Flash in one BIOS for PnP
;			  1. Always compile this code
;			  2. Change some lables from XXXX to MXIC_XXXX ....
;			     so that these labels will not conflict with 
;			     the other *.NVM files

;R03ifdef	SST_PH29EE010

;****************************************************************
;*								*
;*	SUBROUTINES TO SUPPORT SST FLASH ROM			*
;*								*
;****************************************************************

WAIT_COUNT	EQU	10

;[]========================================================================[]
;R03; Ct_Flash_Erase:
; SST010_Flash_Erase :					;R03
;
;	Erase Flash ROM at address FD000h - FDFFFh
;
;Saves : None
;Input : None
;
;Output: CF = 0 , Successful
;	 CF = 1 , Error Erase
;
;[]========================================================================[]
;R03 - starts
		Public	SST010_Flash_Erase
SST010_Flash_Erase	Proc	Near
		clc
		ret
SST010_Flash_Erase	Endp
;R03 - ends

;R03		public	Ct_Flash_Erase
;R03Ct_Flash_Erase	proc	near
;R03; No erasing request for SST flash rom
;R03		clc
;R03		ret
;R03Ct_Flash_Erase	endp
ifndef	Flash_IN_SMBASE		;R13

;[]====================================================================[]
;R03; Ct_Flash_Write :
; SST010_Flash_Write :					;R03
;
;	Program Flash ROM at address FD000h - FDFFFh
;
;Saves :
;Input : Source	= DS : SI
;	 Target	= ES : DI (Range = FD000h-FDFFFh)
;	 Length	= CX
;
;Output: CF = 0 Successful
;	 CF = 1	Error Program
;
;[]====================================================================[]
;R03		public	Ct_Flash_Write
;R03Ct_Flash_Write	proc	near
		public	SST010_Flash_Write		;R03
SST010_Flash_Write	Proc	Near			;R03

		push	ax
		push	cx
		push	si
		push	di

ifndef	AUTO_DETECT_EEPROM_ID					;R11A
		mov	al, 1					;R08
		call	Software_Data_Protection		;R08

		mov	al, 0
		call	Software_Data_Protection
endif;	AUTO_DETECT_EEPROM_ID					;R11A

		mov	ax, cx
		mov	cl, 128
		div	cl

		push	ax

		xor	cx, cx
		mov	cl, al
		jcxz	short Write_Remainder
Block_Loop:
		push	cx
		push	si				;R02
		push	di

		mov	cx, 128
ifdef	ESCD_M2						;R11
; We will trying to ENABLE the data protection on the 28EE011/28EE010 chip
		mov	byte ptr gs:[05555h],0AAh
		mov	byte ptr gs:[0AAAAh],055h
		mov	byte ptr gs:[05555h],0A0h
endif;	ESCD_M2						;R11
@@:
		lodsb
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Ct_Set_Flash
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset Ct_Set_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		inc	di
		loop	short @b
		pop	di
		pop	si				;R02

		call    SST_Check_Toggle_Ready	;wait for toggle bit to be ready

		pop	cx
;R05A ifndef	P6_BIOS_ONLY	     			;R04
;R06		mov	al, es:[di]			;R05
;R06;R05		call	Ct_Get_Flash			;R02
;R06		cmp	al, ds:[si]			;R02
;R06		jne	short Ct_Flash_Write_Fail1	;R02
;R05A endif;	P6_BIOS_ONLY	     			;R04

;R06 - starts
		pusha
		mov	cx, 128
;R05B		repe	cmpsb
@@:							;R05B
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Ct_Get_Flash			;R05B
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset Ct_Get_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		cmp	al, ds:[si]			;R05B
		jne	short @f			;R05B
		inc	si				;R05B
		inc	di				;R05B
		loop	short @b			;R05B
		cmp	al, al				;R05B
@@:							;R05B
		popa
		jne	short Ct_Flash_Write_Fail1
;R06 - ends

		add	si, 128				;R02
		add	di, 128
		loop	short Block_Loop
Write_Remainder:
		pop	ax
		xor	cx, cx
		mov	cl, ah
		jcxz	short Ct_Flash_Write_Exit

		push	cx				;R06
		push	si				;R02
		push	di
ifdef	ESCD_M2						;R11
; We will trying to ENABLE the data protection on the 28EE011/28EE010 chip
		mov	byte ptr gs:[05555h],0AAh
		mov	byte ptr gs:[0AAAAh],055h
		mov	byte ptr gs:[05555h],0A0h
endif;	ESCD_M2						;R11
@@:
		lodsb
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Ct_Set_Flash
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset Ct_Set_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		inc	di
		loop	short @b
		pop	di
		pop	si				;R02

		call    SST_Check_Toggle_Ready	;wait for toggle bit to be ready
		pop	cx				;R06

;R05A ifndef	P6_BIOS_ONLY	   			;R04
;R06		mov	al, es:[di]			;R05
;R05		call	Ct_Get_Flash			;R02
;R06		cmp	al, ds:[si]			;R02
;R06		jne	short Ct_Flash_Write_Fail	;R02
;R05A endif;	P6_BIOS_ONLY		   		;R04

;R06 - starts
		pusha
;R05B		repe	cmpsb
@@:							;R05B
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Ct_Get_Flash			;R05B
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset Ct_Get_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		cmp	al, ds:[si]			;R05B
		jne	short @f			;R05B
		inc	si				;R05B
		inc	di				;R05B
		loop	short @b			;R05B
		cmp	al, al				;R05B
@@:							;R05B
		popa
;R07		jne	short Ct_Flash_Write_Fail1
		jne	short Ct_Flash_Write_Fail	;R07
;R06 - ends

Ct_Flash_Write_Exit:
ifndef	AUTO_DETECT_EEPROM_ID					;R11A
		mov	al, 1
		call	Software_Data_Protection
endif;	AUTO_DETECT_EEPROM_ID					;R11A

		pop	di
		pop	si
		pop	cx
		pop	ax
		clc
		ret

;R02 - start
Ct_Flash_Write_Fail1:
		pop	ax
Ct_Flash_Write_Fail:
ifndef	AUTO_DETECT_EEPROM_ID					;R11A
		mov	al, 1
		call	Software_Data_Protection
endif;	AUTO_DETECT_EEPROM_ID					;R11A

		pop	di
		pop	si
		pop	cx
		pop	ax
		stc
		ret
;R02 - end

;R03Ct_Flash_Write	endp
SST010_Flash_Write	Endp				;R03

ifndef	AUTO_DETECT_EEPROM_ID					;R11A
;[]====================================================================[]
; Routine Name: Software_Data_Protection                                ;
;									;
; Purpose:      This subroutine will either ENABLE or DISABLE the data  ;
;               protection feature on the SST's 28EE011/28EE010 EEPROM. ;
;               See the specification for more information.             ;
;									;
; inputs:                                                               ;
;	ES:	ESCD segment/selector
;       AL:     1 means ENABLE data protection                          ;
;       AL:     0 means DISABLE data protection                         ;
;									;
; outputs:                                                              ;
;       None                                                            ;
;									;
; IMPORTANT NOTICE:  This version of the software will work with both   ;
; ================   the OLD and NEW versions of the 28EE011/010 chips  ;
;									;
;                    The "NEW" version of the chip will use the         ;
;                    following address to perform the programming:      ;
;                          "5555h" and "2AAAh"                          ;
;									;
;                    The "OLD" version of the chip will use the         ;
;                    following address to perform the programming:      ;
;                          "15555h" and "AAAAh"                         ;
;									;
;                    Since the "15555h" and "AAAAh" addresses will work ;
;                    for both versions of the chip, we have decided to  ;
;                    use it in the program.                             ;
;									;
;[]====================================================================[]

Software_Data_Protection        proc    near

		push    ax
		push    si
		push    di
;R12		push	es

;R12ifdef	ESCD_M2					;R09
;R12		push	gs			;R09
;R12		pop	es			;R09
;R12endif;	ESCD_M2					;R09
		push	ax

		mov     si, 02AAAh              ;R05
;R05		mov     si, 0AAAAh              ; ds:si = 0AAAA
		mov     di, 5555h               ; es:di = 15555

		mov     al, 0AAh                ; 1st byte [15555] = AAh
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12

		mov     al, 055h                ; 2nd byte [0AAAA] = 55h
		xchg	si, di
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12
		xchg	si, di

		pop	ax

		cmp     al, 0                   ; Disable or Enable data protection?
		je      SDP_Reset               ; if ZERO, means disable

;
; We will trying to ENABLE the data protection on the 28EE011/28EE010 chip
;

		mov     al, 0A0h                ; 3rd byte [15555] = A0h
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12
		jmp     SDP_Done

SDP_Reset:

;
; We will trying to DISABLE the data protection on the 28EE011/28EE010 chip
;

		mov     al, 80h                 ; 3rd byte [15555] = 80h
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12

		mov     al, 0AAh                ; 4th byte [15555] = AAh
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12

		mov     al, 055h                ; 5th byte [0AAAA] = 55h
		xchg	si, di
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12
		xchg	si, di

		mov     al, 20h                 ; 6th byte [15555] = 20h
;R12ifndef	AUTO_DETECT_EEPROM_ID				;R10
;R12		call	Ct_Set_Flash
;R12else;	AUTO_DETECT_EEPROM_ID				;R10
;R12		mov	dx,offset Ct_Set_Flash		;R10
;R12		call	dx				;R10
;R12endif;	AUTO_DETECT_EEPROM_ID				;R10
		mov	gs:[di], al		;R12

SDP_Done:
		call    SST_Check_Toggle_Ready	; wait for toggle bit to be ready

;R12		pop     es
		pop     di
		pop     si
		pop     ax
		ret

Software_Data_Protection        endp
endif;	AUTO_DETECT_EEPROM_ID					;R11A

;[]====================================================================[]
;[]====================================================================[]

SST_Check_Toggle_Ready	proc    near

;R04 - start
;R05A ifdef	P6_BIOS_ONLY				
;R05A 		push	ax
;R05A 		push	cx
;R05A 		mov	cx,10
;R05A Wait_Again:
;R05A 		call	Wait_10ms
;R05A 		loop	short Wait_Again
;R05A 		pop	cx
;R05A 		pop	ax
;R05A 		clc
;R05A else;	P6_BIOS_ONLY				

		push    ax
		push	bx
		push	di				;R12
		xor	di, di				;R12
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Ct_Get_Flash
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset Ct_Get_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		and     al, 40h
		mov	bx, WAIT_COUNT
SST_CTR_Tog2:
		mov	ah, al
ifndef	AUTO_DETECT_EEPROM_ID				;R10
		call	Wait_10ms
		call	Ct_Get_Flash
else;	AUTO_DETECT_EEPROM_ID				;R10
		mov	dx,offset EEPROM_Wait_10ms	;R10
		call	dx				;R10
		mov	dx,offset Ct_Get_Flash		;R10
		call	dx				;R10
endif;	AUTO_DETECT_EEPROM_ID				;R10
		and     al, 40h
		cmp     al, ah
		clc
		je      SST_CTR_Tog3
		dec	bx
		jnz	short SST_CTR_Tog2
		stc
SST_CTR_Tog3:
		pop	di				;R12
		pop	bx
		pop     ax
;R05A endif;	P6_BIOS_ONLY				
		ret

SST_Check_Toggle_Ready	endp

ifndef	AUTO_DETECT_EEPROM_ID				;R10
Wait_10ms	proc	near
	push	bx
	push	cx
	xor	bx, bx
	mov	cx, 350
	call	Wait_Refresh
	pop	cx
	pop	bx
	ret
Wait_10ms	endp
endif;	AUTO_DETECT_EEPROM_ID				;R10

;R03endif	;SST_PH29EE010
else; Flash_IN_SMBASE		;;R13
;[]====================================================================[]
; SST010_Flash_Write :					;R03
;
;	Program Flash ROM at address FFFFC000h - FFFFDFFFh
;
;Saves :
;Input : Source	= DS : ESI
;	 Target	= ES : EDI (Range = FFFFD000h - FFFFDFFFh)
;	 Length	= CX
;
;	 EEPROM Delay offset 	= DX	;from SMIFlash.asm do'nt 
;
;Output: CF = 0 Successful
;	 CF = 1	Error Program
;
;[]====================================================================[]
		public	SST010_Flash_Write
SST010_Flash_Write	Proc	Near
		pushad
		mov	ax, cx
		shr	ax,7		;ax/128

		xor	ecx, ecx
		mov	cl, al
		jcxz	short Ct_Flash_Write_Exit
Next_Block_Loop:
		push	ecx
		push	esi
		push	edi
		mov	cx, 128
; We will trying to ENABLE the data protection on the 28EE011/28EE010 chip
		mov	byte ptr gs:[0FFFF5555h],0AAh
		mov	byte ptr gs:[0FFFFAAAAh],055h
		mov	byte ptr gs:[0FFFF5555h],0A0h
SST_010_Block_loop:
		mov	al,ds:[esi]
		mov	es:[edi],al
		inc	esi
		inc	edi
		loop	short SST_010_Block_loop
		pop	edi
		pop	esi

		call    SST_Check_Toggle_Ready	;wait for toggle bit to be ready
		pop	ecx			;block loop

		pusha
		mov	cx, 128
Compare_Loop:
		mov	al,es:[edi]		;flash ROM data
		cmp	al, ds:[esi]		;compare with Source
		jne	short Compare_Loop_end
		inc	esi
		inc	edi
		loop	short Compare_Loop
		cmp	al, al
Compare_Loop_end:
		popa
		stc
		jne	short Ct_Flash_Write_Exit

		add	esi, 128
		add	edi, 128
		loop	short Next_Block_Loop
		clc
Ct_Flash_Write_Exit:
		popad
		ret

SST010_Flash_Write	Endp				;R03

;[]======================================================[]
;[]======================================================[]

SST_Check_Toggle_Ready	proc    near
		pusha
		xor	di, di
		mov	al,es:[edi]
		and     al, 40h
		mov	bx, WAIT_COUNT
SST_CTR_Tog2:
		mov	ah, al
		mov	cx,350
		call	dx		;delay time = (30ns)* cx =10.5ms
		mov	al,es:[edi]
		and     al, 40h
		cmp     al, ah
		clc
		je      SST_CTR_Tog3
		dec	bx
		jnz	short SST_CTR_Tog2
		stc
SST_CTR_Tog3:
		popa
		ret

SST_Check_Toggle_Ready	endp

endif; Flash_IN_SMBASE		;;R13

