;	[]===========================================================[]
;
;	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
;----------------------------------------------------------------------------
;R01	04/29/99 BAR	Add READCOM.INC in XGROUP.
;			For post run AutoLoad awdflash.exe used.
;R00	01/19/98 DRS	Initial version
;			Support BIOS can load awdflash.exe from floppy 
;			disk to Memory in Bootblock and POST
;----------------------------------------------------------------------------
		
		include	ReadCOM.EQU
		include	Port61.EQU	;R01
		include	8254.EQU	;R01

File_ID				EQU	'AWDFLASH'
STACKSIZE			EQU	50		

Read_Cluster_Struc	struc			;
	Start_Cluster	   	DW	?	; Logical Sector 1~80x2x18
	Number_Of_Cluster  	DB	?	;
	Max_Continue_Cluster	DB	?	; Max is ss:Sector_per_Track
Read_Cluster_Struc	ends			;

;[]========================================================[]
; Func : Read_Fdd_File_To_Memory
;	  Read floppy file to memory, this file is decided 
;	  by File_ID str
;   In : None
;   In : SS,SP
;  Out : CF = 1 Error occupy
;	 CF = 0 No error
;[]========================================================[]

		public	Read_Fdd_File_To_Memory	

Read_Fdd_File_To_Memory	proc	far		

		;------------------------------------------
		;Reset Floppy Disk

		xor	ax,ax			
		mov	dh,0				
		mov	dl,ss:Readcom_Valid_Drive	
		int	13h

		;------------------------------------------
		;Initial some default value
		mov	ss:Sector_per_Track,80	
		mov	ss:Error_Message,0	
		mov	ss:FAT12_Cluster_Message,0

		;------------------------------------------
		;Read "Boot Record"

		push	es			; ES *******

		mov	bx,ss:Assign_1_Cluster_Segment	
		mov	es,bx			
		xor	bx,bx			; ES:BX 

		mov	ax,0201h		; Read Sector 0(Boot Record)
		mov	cx,0001h
		mov	dh,0				
		mov	dl,ss:Readcom_Valid_Drive	
		int	13h

		;--------------------------------
		; Error Process 
		;--------------------------------
		cmp	ah,0
		je	@f

		;Try again, read sector 0
		mov	ax,0201h
		mov	cx,0001h
		mov	dh,0				
		mov	dl,ss:Readcom_Valid_Drive	
		int	13h

		cmp	ah,0
		je	short @f

		or	ss:Error_Message,No_Target_Disk
		cmp	ah,40h				; Disk not find ?
		jne	short No_Disk	 		; yes
		or	ss:Error_Message,Sector0_Data_Destroy
	No_Disk:
		jmp	Exist_Startup
		
		;--------------------------------
	@@:
		mov	ax,es:Offset_Bytes_per_Sector		
		mov	ss:Bytes_per_Sector,ax

		mov	al,es:Offset_Sector_per_Cluster	
		mov	ss:Sector_per_Cluster,al

		mov	ax,es:Offset_Reserved_Sector
		mov	ss:Reserved_Sector,ax

		mov	ax,es:Offset_Max_File_Entry_Number
		mov	ss:Max_File_Entry_Number,ax	

		mov	ax,es:Offset_Sector_per_FAT		
		mov	ss:Sector_per_FAT,ax

		mov	ax,es:Offset_Sector_per_Track		
		mov	ss:Sector_per_Track,ax

		mov	ax,es:Offset_File_System_Type		
		mov	ss:File_System_Type,ax
		;------------------------------------------

		mov	ax,ss:Reserved_Sector		
		mov	ss:FAT1_Entry_Sector,ax		;01

		mov	ax,ss:Sector_per_FAT
		shl	ax,1				; duplicate FAT1 and FAT2
		add	ax,ss:Reserved_Sector
		mov	ss:File_Entry_Sector,ax

		; each File Directory Entry is 32 bytes
		mov	ax,ss:Bytes_per_Sector
		shr	ax,5				; 32 bytes unit
		mov	ss:File_Entry_per_Sector,al
		mov	ax,ss:Max_File_Entry_Number	
		mov	bl,ss:File_Entry_per_Sector
		div	bl
		mov	bl,ah				; store remaining 
		xor	ah,ah
		add	ax,ss:File_Entry_Sector
		mov	ss:End_File_Entry_Sector,ax	
		cmp	bl,0				; remaining ?
		je	short @f
		inc	ss:End_File_Entry_Sector
	@@:

		;--------------------------------------------------------------
		; Find Target file start cluster in Root Directory Entry field
		;--------------------------------------------------------------

		mov	ax,ss:File_Entry_Sector		
		or	ss:Error_Message,NO_Find_Target_File

Find_File_Entry_Cluster:

		cmp	ax,End_File_Entry_Sector
		jge	Exist_Startup			

		push	ax				; ******
		mov	bx,ss:Assign_1_Cluster_Segment	
		mov	es,bx
		xor	bx,bx				; ES:BX 
		mov	dl,1				; Read 1 Sector
		call	Get_X_Sector

		;--------------------------------
		; Error Process 
		;--------------------------------
		test	ss:Error_Message,Read_Sector_Error	;Error ?
		jz	short @f
		pop	ax				; ******
		inc	ax				; next sector
		jmp	Find_File_Entry_Cluster
	@@:

		movzx	cx,File_Entry_per_Sector
		xor	di,di				; ES:DI

	Find_Next_File_Entry:
		;------------------------------------------
		; Find file entry in Sector Buffer (1 sector)
		;------------------------------------------
		push	ds				; ******
		mov	ax,cs
		mov	ds,ax
  		mov	si,offset File_ID_Str		; DS:SI

		push	cx
		push	di
		mov	cx,File_Name_Len
		rep	cmpsb
		jnz   	short Find_Next_File_NG
		pop	di
		pop	cx
		pop	ds				; ******
		pop	ax				; ******
		jmp	short Find_Next_File_OK

Find_Next_File_NG:
		pop	di
		add	di,20h				; next file entry
		pop	cx
		pop	ds				; ******
		loop	Find_Next_File_Entry

		pop	ax				; ******
		inc	ax
		jmp	Find_File_Entry_Cluster

Find_Next_File_OK:
		and	ss:Error_Message,not NO_Find_Target_File ;clear flag
		mov	ax,es:[di+1Ah]
		mov	ss:File_Start_Cluster_POS,ax

Exist_Find_File_Entry_Cluster:

		;--------------------------------------------------------------
		; Read FAT to memory buffer
		;--------------------------------------------------------------
		mov	ax,ss:Assign_FAT1_Segment	
		mov	es,ax
		xor	bx,bx

		mov	ax,FAT1_Entry_Sector
		mov	dx,ss:Sector_per_FAT	; invalid is DL
		call	Get_X_Sector

		;--------------------------------
		; Error Process 
		;--------------------------------
		test	ss:Error_Message,Read_Sector_Error	;Error ?
		jz	short @f
		or	ss:Error_Message,FAT_Sector_Error
		jmp	Exist_Startup
	@@:

		;------------------------------------------
		; Get ss:Bits_per_Cluster[BP]
		;------------------------------------------
		mov	ss:Bits_per_Cluster,12
		cmp	ss:File_System_Type,'21'	; FAT12 ?
		je	short @f

		mov	ss:Bits_per_Cluster,16
		cmp	ss:File_System_Type,'61'	; FAT16 ?
		je	short @f
		or	ss:Error_Message,No_Support_FAT_Format	;set error flag
		jmp	Exist_Startup
	@@:

		;--------------------------------------------------------------
		; Establish File Sector Count Structure
		;--------------------------------------------------------------

		mov	ax,ss:File_Start_Cluster_POS
		mov	ss:Now_Cluster_Pos,ax

		push	ds				; ****** DS

		mov	ax,ss:Cluster_Data_Buffer_Seg	;Initial value 
		mov	ds,ax
		xor	si,si				; DS:SI

Next_File_Count_Struc:			

		mov	ax,ss:Now_Cluster_Pos		; Initial
		mov	ds:[si].Start_Cluster,ax	

		;
		add	ax,ss:End_File_Entry_Sector
		sub	ax,2
		call	Phy_Trans_to_Log		; Get Phy_Sector 
		mov	bx,ss:Sector_per_Track		; Invalid BL	 
		sub	bl,ss:Phy_Sector				 
		inc 	bl						 
		mov	ds:[si].Max_Continue_Cluster,bl			 
		;
		mov	ds:[si].Number_Of_Cluster,1

	Establish_File_Struc_Loop:

		call	Get_Contents_Of_Cluster_Pos	; Get BX
		mov	ax,bx
		sub	ax,ss:Now_Cluster_Pos
		cmp	ax,1				; Continue ?
		jne	short No_Continue		; NO
		
		mov	ss:Now_Cluster_Pos,bx		

		mov	al,ds:[si].Number_Of_Cluster	
		cmp	al,ds:[si].Max_Continue_Cluster 
		jb	@f
		add	si,SIZE Read_Cluster_Struc	; Next Struc
		jmp	Next_File_Count_Struc
	@@:
		inc	ds:[si].Number_Of_Cluster
		jmp	short Establish_File_Struc_Loop

	No_Continue:
		;------------------------------------------
		; Not Continue ?
		;------------------------------------------

		mov	ss:Now_Cluster_Pos,bx
		add	si,SIZE Read_Cluster_Struc	; Next Struc

		cmp	ss:Now_Cluster_Pos,0FFFh	; FAT12 EOF ?
		je	short Establish_File_Count_Exit

		cmp	ss:Now_Cluster_Pos,0FFFFh	; FAT16 EOF ?
		je	short Establish_File_Count_Exit
		jmp	Next_File_Count_Struc

Establish_File_Count_Exit:
		mov	ds:[si].Start_Cluster,0FFFFh	   
		mov	ds:[si].Number_Of_Cluster,0FFh	   
		mov	ds:[si].Max_Continue_Cluster,0FFh	   
		pop	ds				; ****** DS

		;--------------------------------------------------------------
		; Copy File contents to Memory Buffer
		;--------------------------------------------------------------

		push	ds				; ****** DS

		mov	ax,ss:Cluster_Data_Buffer_Seg	;Initial value 
		mov	ds,ax
		xor	si,si				; DS:SI

		mov	ax,ss:File_Start_Cluster_POS
		mov	ss:Now_Cluster_Pos,ax

		mov	bx,ss:Assign_COM_Buf_Segment	
		mov	es,bx
		xor	bx,bx				; ES:BX

	Copy_File_To_Buffer_Loop:

		mov	ax,ds:[si].Start_Cluster
		add	ax,ss:End_File_Entry_Sector	; Cluster transfer to Sector
		sub	ax,2		; Because Cluster start from 2

		movzx	dx,ds:[si].Number_Of_Cluster	; Invalid DL
		push	es				;;;;;;
		push	bx				;;;;;;
		call	Get_X_Sector
		pop	bx				;;;;;;
		pop	es				;;;;;;

		;--------------------------------
		; Error Process 
		;--------------------------------
		test	ss:Error_Message,Read_Sector_Error ;Error ?
		jz	short @f		     	   ;NO	
		jmp	short Copy_File_To_Buffer_OK	
	@@:

		mov	ax,ss:Bytes_per_Sector
		movzx	cx,ds:[si].Number_Of_Cluster
		mul	cx				; Get (DX,AX)

		;DX shoudle be 0
		add     bx,ax				; bytes
		jnc	@f				; over 64K

		mov	ax,es
		add	ax,1000h
		mov	es,ax

@@:
		add	si,SIZE Read_Cluster_Struc	; Next Struc
		cmp	ds:[si],0FFFFh			; Struc END ?
		je	short Copy_File_To_Buffer_OK	
		jmp	short Copy_File_To_Buffer_Loop

Copy_File_To_Buffer_OK:

		pop	ds				; ****** DS

		;--------------------------------------------------------------
Exist_Startup:								

		cmp	ss:Error_Message,0		; error ?
		je	short No_Error_Message		; NO

		cmp	ss:Run_Path,POST		; Called by POST ? 
		je	short Four_Beeps		; yes

		lea	ax,Error1
		mov	cx,Error1_Len
		test	ss:Error_Message,No_Find_Target_File
		jnz	short Show_It

		lea	ax,Error5
		mov	cx,Error5_Len
		test	ss:Error_Message,No_Target_Disk
		jnz	short Show_It

		lea	ax,Error3
		mov	cx,Error3_Len
		test	ss:Error_Message,Sector0_Data_Destroy
		jnz	short Show_It

		lea	ax,Error4
		mov	cx,Error4_Len
		test	ss:Error_Message,FAT_Sector_Error
		jnz	short Show_It

		lea	ax,Error2 		; Load Awdfalsh.exe File Fail!'
		mov	cx,Error2_Len
	Show_It:
		mov	dx,0ff01h
;R01		call	Display_Str
		call	Display_Str1		;R01

		lea	ax,BAD_DISK_MSG2
		mov	cx,BAD_DISK_MSG2_Len
		mov	dx,0ff01h
		call	Display_Str1		;R01
;R01		call	Display_Str

		;--------------------------------
		; 4 times Long Beep sound
		;--------------------------------
	Four_Beeps:

		mov	dh,04
	@@:
		mov	bl,6
;R01		call	SND_SPKR
		call	SEND_SPKR	;R01
		loop	short $
		dec	dh
		jnz	short @b

		stc				; Error report 
		jmp	Go_Retrun

No_Error_Message:

		clc
Go_Retrun:

		mov	dx,3f2h			;turn off FDD LED
		mov	al,0ch
		out	dx,al			

		pop	es			; ES *******

		retf				

Read_Fdd_File_To_Memory	endp

;[]--------------------------------------------------------[]
;[]--------------------------------------------------------[]
File_Name_Len	EQU	8
File_ID_Str	db	File_ID			
File_ID_Str_Len	EQU	($ - offset File_ID_Str)
if (File_ID_Str_Len LT File_Name_Len)
		db	(File_Name_Len-File_ID_Str_Len) DUP (' ')
endif	

;[]--------------------------------------------------------[]
Error1		db	'!! ERROR -- AWDFLASH.EXE Not Found !! '
Error1_LEN		EQU	$ - offset Error1

Error2		db	'!! ERROR -- Load AWDFLASH.EXE Failed !!'
Error2_LEN		EQU	$ - offset Error2

Error3		db	'!! ERROR -- Bad Floppy Boot Sector !!'
Error3_LEN		EQU	$ - offset Error3

Error4		db	'!! ERROR -- Bad Floppy FAT Sector !!'
Error4_LEN		EQU	$ - offset Error4

Error5		db	'!! ERROR -- Floppy Disk Not Found !!'
Error5_LEN		EQU	$ - offset Error5

Load_Awdflash_Str:	db	'Automatic Load AWDFLASH.EXE .....'  	;R01
Load_Awdflash_LEN	EQU	$ - offset Load_Awdflash_Str		;R01
;R01 Load_Awdflash:	db	'Automatic Load AWDFLASH.EXE .....'
;R01 Load_Awdflash_LEN	EQU	$ - offset Load_Awdflash

BAD_DISK_MSG2:	db	'Replace the DISK AND PRESS ENTER'
BAD_DISK_MSG2_LEN	EQU	$ - offset BAD_DISK_MSG2


;[]========================================================[]
; Func : Bt_Initial_Para1
; 	 Transfer some parameter to Awdflash.exe
;[]========================================================[]
Bt_Initial_Para1	proc	far

		mov	ss:Readcom_Valid_Drive,0 	;Drive A 
		mov	ss:Run_Path,BOOTROM

;R01		mov	ss:Cluster_Data_Buffer_Seg,2F00h	
;R01		mov	ss:Assign_1_Cluster_Segment,2000h	
;R01		mov	ss:Assign_FAT1_Segment,2000h		
;R01		mov	ss:Assign_COM_Buf_Segment,2000h		
;R01 - start
		mov	ss:Cluster_Data_Buffer_Seg,Cluster_Buffer_Value	
		mov	ss:Assign_1_Cluster_Segment,Assign_1_Cluster_Value
		mov	ss:Assign_FAT1_Segment,Assign_FAT1_Value 	
		mov	ss:Assign_COM_Buf_Segment,Assign_COM_Buf_Value 	
;R01 - end

		retf

Bt_Initial_Para1	endp

;[]========================================================[]
; Func : Bt_Initial_Para2
; 	 Transfer some parameter to Awdflash.exe
;[]========================================================[]
Bt_Initial_Para2	proc	far

		;Transfer BIOS_ID to awdflash.exe
		push	ds
		push	es

		mov	ax,cs				; DS:SI
		mov	ds,ax
		mov	si,0FFE8h

		mov	ax,ss
		mov	es,ax
		mov	di,bp
		add	di,BIOS_ID_String
		mov	cx,8				; 8 bytes
		rep	movsb

		pop	es
		pop	ds

;R01		mov	word ptr ss:Awdflash_Seg[bp],2000h
;R01		mov	word ptr ss:Source_Segment[bp],3000h
;R01		mov	word ptr ss:Bios_Segment[bp],7000h
;R01		mov	word ptr ss:Decompress_Segment[bp],8000h
;R01		mov	word ptr ss:Buffer1_Segment[bp],8000h
;R01		mov	word ptr ss:Buffer2_Segment[bp],5000h
;R01 - start
		mov	word ptr ss:Awdflash_Seg[bp],Awd_Source_Value
ifndef Flash_64K_Unit
		mov	word ptr ss:Source_Segment[bp],Source_Seg_Value
		mov	word ptr ss:Bios_Segment[bp],Bios_Seg_Value	
		mov	word ptr ss:Decompress_Segment[bp],Decompress_Seg_Value
		mov	word ptr ss:Buffer1_Segment[bp],Buffer1_Seg_Value
		mov	word ptr ss:Buffer2_Segment[bp], Buffer2_Seg_Value
endif; Flash_64K_Unit
;R01 - ends
		mov	byte ptr ss:Valid_Drive[bp],0 	;Drive A 
		retf
Bt_Initial_Para2	endp

;[]========================================================[]
; FUNC : Get_Contents_Of_Cluster_Pos
;   IN : ss:Now_Cluster_Pos
;  OUT : BX -- FAT12 0000xxxx xxxxxxxx
;	       FAT16 xxxxxxxx xxxxxxxx		
; Note : Code of FAT16 don't support 
;[]========================================================[]
Get_Contents_Of_Cluster_Pos	proc	near

		push	es			; ******
		push	di			; ******

		mov	ss:FAT12_Cluster_Message,0 ;Initial value
		mov	ax,ss:Now_Cluster_Pos
		movzx	bx,ss:Bits_per_Cluster	; 12bit or 16bit
		mul	bx			;get (DX,AX)
		mov	bx,8			; 8 bit
		div	bx			;get DX - remaining (bits)
						;    AX - quotient (bytes)	
		cmp	ss:Bits_per_Cluster,16
		je	FAT16_Format

	FAT12_Format:

		cmp	dx,0			; remaining = 0 ?
		je	short @f		; yes
		or	ss:FAT12_Cluster_Message,Get_High_Nibble
		inc	ax				
	@@:
		;--------------------------------
		; AX - position of complete 8bit in FAT1 memory buffer
		;--------------------------------
		mov	bx,ss:Assign_FAT1_Segment
		mov	es,bx
		mov	di,ax
		movzx	bx,byte ptr es:[di]	; Get 1 Byte

		push	bx			; ******

		call	Is_High_Nibble		; use high nibble ?
		jnz	short High_Nibble	; yes
		inc	ax
		jmp	short @f
High_Nibble:
		dec	ax
@@:
		;--------------------------------
		; AX - position of another 4bit memory buffer
		;--------------------------------
		mov	bx,ss:Assign_FAT1_Segment
		mov	es,bx
		mov	di,ax
		movzx	ax,byte ptr es:[di]	; Get 1 Byte

		call	Is_High_Nibble		; use High nibble ?
		jnz	@f			; yes
		and	al,00001111b		; use Low nibble
		pop	bx			; ******
		mov	bh,al		
		jmp	End_Get_Contents_Of_Cluster
@@:
		;--------------------------------
		and	al,11110000b		; use High nibble
		shr	al,4
		pop	bx			; ******
		shl	bx,4
		or	bl,al
		jmp	End_Get_Contents_Of_Cluster
		
	FAT16_Format:		

End_Get_Contents_Of_Cluster:

		pop	di			; ******
		pop	es			; ******
		ret

Get_Contents_Of_Cluster_Pos	endp

;[]========================================================[]
; FUNC : Is_High_Nibble
;  OUT : ZF = 1 (Get Low nibble)
;	      0 (Get High nibble)	
;[]========================================================[]
Is_High_Nibble 	proc	near
		test	ss:FAT12_Cluster_Message,Get_High_Nibble
		ret
Is_High_Nibble	endp

;[]========================================================[]
; FUNC : Get_X_Sector
;
;   IN : AX -- Logical Sector 1 ~ 80x2x18 (Track * Side * Sector)	
;	 DL -- Number of secotr will be read
;	 ES:BX (any Segment)
;  OUT : AH = 00 (right)
;	      XX (mistake)
;	 data in ES:BX buffer 
;[]========================================================[]
Get_X_Sector	proc	near

		; clear flag
		and	ss:Error_Message,not Read_Sector_Error 	

	 	push	dx
		push	bx
		call	Phy_Trans_to_Log		; use AX
		pop	bx
	 	pop	dx

		mov	ah,02h
		mov	al,dl
		mov	ch,Phy_Track
		mov	cl,Phy_Sector
		mov	dh,Phy_Side
		mov	dl,ss:Readcom_Valid_Drive	
		int	13h
			
		cmp	ah,0				; Read File NG ?
		je	short @f			; NO
		or	ss:Error_Message,Read_Sector_Error
	@@:	
		ret

Get_X_Sector	endp

;[]========================================================[]
; FUNC : Phy_Trans_to_Log	
;	 Physical sector transfer to logical sector
;
; IN   : AX -- Logical Sector 1 ~ 80x2x18 (Track * Side * Sector) 
; OUT  : Phy_Track		
;	 Phy_Side		
;	 Phy_Sector		
;[]========================================================[]
Phy_Trans_to_Log	proc	near

		push	ax
		mov	bx,ss:Sector_per_Track
		shl	bl,1				; 1 Track = Side 0/1
		div	bl
		mov	ss:Phy_Track,al			; quotient

		mov	al,ah
		xor	ah,ah
		mov	bx,ss:Sector_per_Track
		div	bl
		mov	ss:Phy_Side,al			; quotient

		; Sector start from 1 in bios function call
		inc	ah
		mov	ss:Phy_Sector,ah
		pop	ax

		ret

Phy_Trans_to_Log	endp

;R01 - start
Display_Str1	Proc	Near

;	Entry :	AX - String offset
;		CX - String length
;		DH - Display row position, if = 0ffh then this row plus DL
;						0feh then don't move cursor
;		DL - Display column position

		push	es
		push	ax
		push	bx
		push	bp

		mov	bp,ax
		mov	bx,7
		cmp	dh,0feh
		jb	short Not_Special1
		push	cx
		push	dx
		mov	ah,3
		int	10h
		pop	ax
		je	short @F
		add	dh,al
		xor	dl,dl

		cmp	dh,24
		jbe	short @F
		push	bx
		push	dx
		mov	ax,601h
		mov	bh,7
		xor	cx,cx
		mov	dx,184fh
		int	10h
		pop	dx
		pop	bx
		mov	dh,24
@@:
		pop	cx
Not_Special1:
		mov	ax,0f000h
		mov	es,ax
		mov	ax,1301h
		int	10h

		pop	bp
		pop	bx
		pop	ax
		pop	es
		ret
Display_Str1	EndP

SEND_SPKR	PROC	NEAR
; RETURNS CX 0
		MOV	CX,533H
		MOV	AL,0B6H
		OUT	CTRL8254,AL
		MOV	AX,CX
		NEWIODELAY
		OUT	DATA8254+2,AL
		MOV	AL,AH
		NEWIODELAY
		OUT	DATA8254+2,AL
		IN	AL,SYS1
		MOV	AH,AL
		OR	AL,3
		NEWIODELAY
		OUT	SYS1,AL

@@:					
		mov	cx,5000h	
		ALIGN	4
B_WAIT1:
		newiodelay		
		newiodelay		
		newiodelay		
		newiodelay		
		LOOP	SHORT B_WAIT1
		DEC	BL
		jnz	short @B	

		MOV	AL,AH
		OUT	SYS1,AL
		RET
SEND_SPKR	ENDP

;R01 - end



