;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R03	01/28/99 BAR	Support update ESCD DMI in SMM mode.
;			define switch "Flash_IN_SMBASE"
;R02	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.)
;R01	12/05/96 AVN	Suppost Both With/out Define ESCD_M2 and Save Code.
;R00	08/12/96 AVN	Initial Version

ifdef	Flash_16K_8K_8K_Unit

;****************************************************************
;*								*
;*	SUBROUTINES TO SUPPORT ATMEL 29C020 FLASH ROM		*
;*								*
;****************************************************************

WAIT_COUNT	EQU	10

;[]========================================================================[]
; ATMEL29C020_Flash_Erase :
;
;	Erase Flash ROM at address FA000h - FBFFFh
;
;Saves : None
;Input : None
;
;Output: CF = 0 , Successful
;	 CF = 1 , Error Erase
;
;[]========================================================================[]
ATMEL29C020_Flash_Erase	Proc	Near
		clc
		ret
ATMEL29C020_Flash_Erase	Endp

ifndef	Flash_IN_SMBASE		;R03
;[]====================================================================[]
; ATMEL29C020_Flash_Write :
;
;	Program Flash ROM at address FA000h - FBFFFh
;
;Saves :
;Input : Source	= DS : SI
;	 Target	= ES : DI (Range = FA000h-FBFFFh)
;	 Length	= CX
;
;Output: CF = 0 Successful
;	 CF = 1	Error Program
;
;[]====================================================================[]
ATMEL29C020_Flash_Write	Proc	Near

		push	ax
		push	cx
		push	si
		push	di

		mov	al, 0
		call	ATMEL29C020_Software_Data_Protection

		xor	dx, dx
		mov	ax, cx
		mov	cx, 256
		div	cx

		push	dx

		mov	cx, ax
		jcxz	short ATMEL29C020_Write_Remainder
ATMEL29C020_Block_Loop:
		push	cx
		push	si
		push	di
		mov	cx, 256
@@:
		lodsb
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01
		inc	di
		loop	short @b
		pop	di
		pop	si

		call    ATMEL29C020_Check_Toggle_Ready	;wait for toggle bit to be ready

		pop	cx

		pusha
		mov	cx, 256
@@:
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Get_Flash
;R01 else;	ESCD_M2
;R01 		mov	al,es:[di]
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Get_Flash		; R01
		call	dx				; R01
		cmp	al, ds:[si]
		jne	short @f
		inc	si
		inc	di
		loop	short @b
		cmp	al, al
@@:
		popa
		jne	short ATMEL29C020_Write_Fail1

		add	si, 256
		add	di, 256
		loop	short ATMEL29C020_Block_Loop

ATMEL29C020_Write_Remainder:
		pop	cx
		jcxz	short ATMEL29C020_Write_Exit

		push	cx
		push	si
		push	di
@@:
		lodsb
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01
		inc	di
		loop	short @b
		pop	di
		pop	si

		call    ATMEL29C020_Check_Toggle_Ready	;wait for toggle bit to be ready
		pop	cx

		pusha
@@:
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Get_Flash
;R01 else;	ESCD_M2
;R01 		mov	al,es:[di]
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Get_Flash		; R01
		call	dx				; R01
		cmp	al, ds:[si]
		jne	short @f
		inc	si
		inc	di
		loop	short @b
		cmp	al, al
@@:
		popa
		jne	short ATMEL29C020_Write_Fail

ATMEL29C020_Write_Exit:
		mov	al, 1
		call	ATMEL29C020_Software_Data_Protection

		pop	di
		pop	si
		pop	cx
		pop	ax
		clc
		ret

ATMEL29C020_Write_Fail1:
		pop	ax
ATMEL29C020_Write_Fail:
		mov	al, 1
		call	ATMEL29C020_Software_Data_Protection

		pop	di
		pop	si
		pop	cx
		pop	ax
		stc
		ret

ATMEL29C020_Flash_Write	Endp

;[]====================================================================[]
; Routine Name: ATMEL29C020_Software_Data_Protection                    ;
;									;
; Purpose:      This subroutine will either ENABLE or DISABLE the data  ;
;               protection feature on the ATMEL 29C020 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.                             ;
;									;
;[]====================================================================[]

ATMEL29C020_Software_Data_Protection        proc    near

		push    ax
		push    si
		push    di
;R02		push	es

		push	ax

		mov     si, 02AAAh
		mov     di, 5555h		; es:di = 15555

		mov     al, 0AAh		; 1st byte [15555] = AAh
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01

		mov     al, 055h		; 2nd byte [0AAAA] = 55h
		xchg	si, di
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01
		xchg	si, di

		pop	ax

		cmp     al, 0				; Disable or Enable data protection?
		je      short ATMEL29C020_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
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01
		jmp     short ATMEL29C020_SDP_Done

ATMEL29C020_SDP_Reset:

;
; We will trying to DISABLE the data protection on the 28EE011/28EE010 chip
;

		mov     al, 80h			; 3rd byte [15555] = 80h
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01

		mov     al, 0AAh		; 4th byte [15555] = AAh
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01

		mov     al, 055h		; 5th byte [0AAAA] = 55h
		xchg	si, di
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01
		xchg	si, di

		mov     al, 20h			; 6th byte [15555] = 20h
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Set_Flash
;R01 else;	ESCD_M2
;R01 		mov	es:[di],al
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Set_Flash		; R01
		call	dx				; R01

ATMEL29C020_SDP_Done:
		call    ATMEL29C020_Check_Toggle_Ready	; wait for toggle bit to be ready

;R02		pop     es
		pop     di
		pop     si
		pop     ax
		ret

ATMEL29C020_Software_Data_Protection        endp

;[]====================================================================[]
;[]====================================================================[]

ATMEL29C020_Check_Toggle_Ready	proc    near

		push    ax
		push	bx
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Get_Flash
;R01 else;	ESCD_M2
;R01 		mov	al,es:[di]
;R01 endif;	ESCD_M2
		mov	dx,offset Ct_Get_Flash		; R01
		call	dx				; R01
		and     al, 40h
		mov	bx, WAIT_COUNT
ATMEL29C020_CTR_Tog2:
		mov	ah, al
;R01		call	ATMEL29C020_Wait_10ms
;R01 ifndef	ESCD_M2
;R01 		call	Ct_Get_Flash
;R01 else;	ESCD_M2
;R01 		mov	al,es:[di]
;R01 endif;	ESCD_M2
		mov	dx,offset EEPROM_Wait_10ms	; R01
		call	dx				; R01
		mov	dx,offset Ct_Get_Flash		; R01
		call	dx				; R01
		and     al, 40h
		cmp     al, ah
		clc
		je      short ATMEL29C020_CTR_Tog3
		dec	bx
		jnz	short ATMEL29C020_CTR_Tog2
		stc
ATMEL29C020_CTR_Tog3:
		pop	bx
		pop     ax
		ret

ATMEL29C020_Check_Toggle_Ready	endp

;R01 ATMEL29C020_Wait_10ms	proc	near
;R01 		push	bx
;R01 		push	cx
;R01 		xor	bx, bx
;R01 		mov	cx, 350
;R01 
;R01 		PUSH	AX			; save ax.
;R01 
;R01 		ALIGN	4
;R01 ATMEL_WR_OUTER_LP:
;R01 ATMEL_WR_INNER_LP:
;R01 ATMEL_WR_STATE_0:
;R01 		IN	AL,SYS1
;R01 		TEST	AL,010H
;R01 		JZ	SHORT ATMEL_WR_STATE_0
;R01 
;R01 		ALIGN	4
;R01 ATMEL_WR_STATE_1:
;R01 		IN	AL,SYS1
;R01 		TEST	AL,010H
;R01 		JNZ	SHORT ATMEL_WR_STATE_1
;R01 		LOOP	SHORT ATMEL_WR_INNER_LP
;R01 
;R01 		OR	BX,BX
;R01 		JZ	SHORT ATMEL_WR_EXIT
;R01 		DEC	BX
;R01 		JMP	SHORT ATMEL_WR_OUTER_LP
;R01 
;R01 ATMEL_WR_EXIT:	POP	AX			; restore ax
;R01 
;R01 		pop	cx
;R01 		pop	bx
;R01 		ret
;R01 ATMEL29C020_Wait_10ms	endp
;R03 - start
else;	Flash_IN_SMBASE
;[]====================================================================[]
; ATMEL29C020_Flash_Write :
;
;	Program Flash ROM at address FFFF8000h - FFFFBFFFh
;
;Saves :
;Input : Source	= DS : ESI
;	 Target	= ES : EDI (Range = FFFF8000h - FFFFBFFFh)
;	 Length	= CX
;
;Output: CF = 0 Successful
;	 CF = 1	Error Program
;
;[]====================================================================[]
ATMEL29C020_Flash_Write	Proc	Near

		pusha
		shr	cx, 8		;ax= ax/256
		jcxz	short ATMEL29C020_Write_Exit
ATMEL29C020_Block_Loop:
		push	ecx
		push	esi
		push	edi
		mov	ecx, 256
		mov	byte ptr es:[0FFFF5555h],0AAh
		mov	byte ptr es:[0FFFFAAAAh],055h
		mov	byte ptr es:[0FFFF5555h],0A0h
At_020_Block_loop:
 		mov	al,byte ptr ds:[esi]		;Read source
 		mov	byte ptr es:[edi],al		;write data
		inc	esi
		inc	edi
		loop	short At_020_Block_loop

		pop	edi
		pop	esi

		call    ATMEL29C020_Check_Toggle_Ready	;wait for toggle bit to be ready

		pop	ecx

		pusha
		mov	cx, 256
At_020_Compare_Loop:
 		mov	al,byte ptr es:[edi]
		cmp	al, ds:[esi]
		jne	short At_020_Compare_Loop_end
		inc	esi
		inc	edi
		loop	short At_020_Compare_Loop
		cmp	al, al			;set e flag
At_020_Compare_Loop_end:
		popa
		stc
		jne	short ATMEL29C020_Write_Exit
		add	esi, 256
		add	edi, 256
		loop	short ATMEL29C020_Block_Loop
		clc
ATMEL29C020_Write_Exit:
		popa
		ret

ATMEL29C020_Flash_Write	Endp

;[]====================================================================[]
;[]====================================================================[]

ATMEL29C020_Check_Toggle_Ready	proc    near

		push    ax
		push	bx
		mov	al, byte ptr es:[edi]
		and     al, 40h
		mov	bx, WAIT_COUNT
ATMEL29C020_CTR_Tog2:
		mov	ah, al
		push	cx
		mov	cx,350
		call	dx		;delay time = (30ns)* cx =10.5ms
		pop	cx
		mov	al, byte ptr es:[edi]
		and     al, 40h
		cmp     al, ah
		clc
		je      short ATMEL29C020_CTR_Tog3
		dec	bx
		jnz	short ATMEL29C020_CTR_Tog2
		stc
ATMEL29C020_CTR_Tog3:
		pop	bx
		pop     ax
		ret

ATMEL29C020_Check_Toggle_Ready	endp

endif;	Flash_IN_SMBASE		
;R03 - end
endif;	Flash_16K_8K_8K_Unit

